From 2a5c8fdb40d43d832e8a514d4897ea730740f3b5 Mon Sep 17 00:00:00 2001 From: nitinanand Date: Wed, 20 Mar 2019 10:26:08 +0530 Subject: [PATCH] sample worklet with multiEvent usage Change-Id: I03f4609714fc1df564cca87223890663788a2acc --- .../ofoverlay/impl/OfOverlayWorkflow.java | 17 +++ .../org/onosproject/ofoverlay/impl/Ovs.java | 103 ++++++++++++++++++ .../network-cfg-ovs-cr-multiEvent-wf.json | 41 +++++++ 3 files changed, 161 insertions(+) create mode 100755 apps/workflow/ofoverlay/test-cfg/network-cfg-ovs-cr-multiEvent-wf.json diff --git a/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/OfOverlayWorkflow.java b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/OfOverlayWorkflow.java index 5fb8cd2bc6..ec6a091b00 100644 --- a/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/OfOverlayWorkflow.java +++ b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/OfOverlayWorkflow.java @@ -97,6 +97,23 @@ public class OfOverlayWorkflow { .build(); workflowStore.register(workflow); + // registering new workflow definition based on multi-event handling + uri = URI.create("of-overlay.workflow-nova-multiEvent-test"); + workflow = ImmutableListWorkflow.builder() + .id(uri) + //.attribute(WorkflowAttribute.REMOVE_AFTER_COMPLETE) + .chain(Ovs.CreateOvsdbDevice.class.getName()) + .chain(Ovs.UpdateOvsVersion.class.getName()) + .chain(Ovs.UpdateOverlayBridgeId.class.getName()) + .chain(Ovs.CreateOverlayBridgeMultiEvent.class.getName()) + .chain(Ovs.UpdateUnderlayBridgeId.class.getName()) + .chain(Ovs.CreateUnderlayBridge.class.getName()) + .chain(Ovs.CreateOverlayBridgeVxlanPort.class.getName()) + .chain(Ovs.AddPhysicalPortsOnUnderlayBridge.class.getName()) + .chain(Ovs.ConfigureUnderlayBridgeLocalIp.class.getName()) + .build(); + workflowStore.register(workflow); + uri = URI.create("of-overlay.clean-workflow-nova"); workflow = ImmutableListWorkflow.builder() .id(uri) diff --git a/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/Ovs.java b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/Ovs.java index 428688b5c5..ef75806e47 100644 --- a/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/Ovs.java +++ b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/Ovs.java @@ -65,6 +65,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Set; import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; @@ -630,6 +631,108 @@ public final class Ovs { } } + /** + * Work-let class for creating overlay openflow bridge. + */ + public static class CreateOverlayBridgeMultiEvent extends AbstractWorklet { + + @JsonDataModel(path = MODEL_MGMT_IP) + String strMgmtIp; + + @JsonDataModel(path = MODEL_OVSDB_PORT) + Integer intOvsdbPort; + + @JsonDataModel(path = MODEL_OVS_DATAPATH_TYPE) + String strOvsDatapath; + + @JsonDataModel(path = MODEL_OF_DEVID_OVERLAY_BRIDGE, optional = true) + String strOfDevIdOverlay; + + @Override + public boolean isNext(WorkflowContext context) throws WorkflowException { + + check(strOfDevIdOverlay != null, "invalid strOfDevIdOverlay"); + return !OvsUtil.isAvailableBridge(context, DeviceId.deviceId(strOfDevIdOverlay)); + } + + @Override + public void process(WorkflowContext context) throws WorkflowException { + + check(strOfDevIdOverlay != null, "invalid strOfDevIdOverlay"); + BridgeConfig bridgeConfig = OvsUtil.getOvsdbBehaviour(context, strMgmtIp, BridgeConfig.class); + List ofControllers = OvsUtil.getOpenflowControllerInfoList(context); + DeviceId ofDeviceId = DeviceId.deviceId(strOfDevIdOverlay); + + if (ofControllers == null || ofControllers.size() == 0) { + throw new WorkflowException("Invalid of controllers"); + } + + Optional optBd = OvsUtil.getBridgeDescription(bridgeConfig, BRIDGE_OVERLAY); + if (!optBd.isPresent()) { + + Set eventHints = Sets.newHashSet(ofDeviceId.toString()); + + context.waitAnyCompletion(DeviceEvent.class, eventHints, + () -> OvsUtil.createBridge(bridgeConfig, + BRIDGE_OVERLAY, + OvsUtil.bridgeDatapathId(ofDeviceId), + ofControllers, + OvsUtil.buildOvsDatapathType(strOvsDatapath)), + TIMEOUT_DEVICE_CREATION_MS + ); + return; + + } else { + BridgeDescription bd = optBd.get(); + if (OvsUtil.isEqual(ofControllers, bd.controllers())) { + log.error("{} has valid controller setting({})", BRIDGE_OVERLAY, bd.controllers()); + context.completed(); + return; + } + + OvsdbClientService ovsdbClient = OvsUtil.getOvsdbClient(context, strMgmtIp, intOvsdbPort); + if (ovsdbClient == null || !ovsdbClient.isConnected()) { + throw new WorkflowException("Invalid ovsdb client for " + strMgmtIp); + } + + // If controller settings are not matched, set controller with valid controller information. + Set eventHints = Sets.newHashSet(ofDeviceId.toString()); + + context.waitAnyCompletion(DeviceEvent.class, eventHints, + () -> ovsdbClient.setControllersWithDeviceId(bd.deviceId().get(), ofControllers), + TIMEOUT_DEVICE_CREATION_MS + ); + return; + } + } + + @Override + public boolean isCompleted(WorkflowContext context, Event event)throws WorkflowException { + if (!(event instanceof DeviceEvent)) { + return false; + } + DeviceEvent deviceEvent = (DeviceEvent) event; + Device device = deviceEvent.subject(); + switch (deviceEvent.type()) { + case DEVICE_ADDED: + case DEVICE_AVAILABILITY_CHANGED: + case DEVICE_UPDATED: + return context.getService(DeviceService.class).isAvailable(device.id()); + default: + return false; + } + } + + @Override + public void timeout(WorkflowContext context) throws WorkflowException { + if (!isNext(context)) { + context.completed(); //Complete the job of worklet by timeout + } else { + super.timeout(context); + } + } + } + /** * Work-let class for updating underlay bridge device id. */ diff --git a/apps/workflow/ofoverlay/test-cfg/network-cfg-ovs-cr-multiEvent-wf.json b/apps/workflow/ofoverlay/test-cfg/network-cfg-ovs-cr-multiEvent-wf.json new file mode 100755 index 0000000000..6f9d2a510e --- /dev/null +++ b/apps/workflow/ofoverlay/test-cfg/network-cfg-ovs-cr-multiEvent-wf.json @@ -0,0 +1,41 @@ +{ + "apps": { + "org.onosproject.workflow": { + "workflow" : { + "rpc" : [ + { + "op" : "workflow.invoke", + "params" : { + "workplace" : "Nova-000", + "id" : "of-overlay.workflow-nova-multiEvent-test", + "data" : { + + "mgmtIp" : "192.168.10.8", + "ovsdbPort" : 6641, + + "sshAccessInfo" : { + "remoteIp" : "192.168.10.8", + "port" : 22, + "user" : "root", + "password" : "iloveyou", + "keyfile" : "~/.ssh/id_rsa" + }, + + "ovsDatapathType" : "system", + "physicalPorts" : [ "enp4s2" ], + "vtepIp" : "120.0.0.200/24", + + "annotations" : { + "rackId" : 1, + "rackPosition" : 3 + } + + } + }, + "id" : "00001@10.0.0.1" + } + ] + } + } + } +}