'Static data model implementation in Worklet
Change-Id: Ic5eeb26eaea547523befd509f9f48281cb4c2031
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 cbddfc7..2267337 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
@@ -21,6 +21,8 @@
import org.onosproject.workflow.api.WorkflowExecutionService;
import org.onosproject.workflow.api.WorkflowStore;
import org.onosproject.workflow.api.WorkplaceStore;
+import org.onosproject.workflow.api.DefaultWorkletDescription;
+import org.onosproject.workflow.api.WorkflowException;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
@@ -57,6 +59,8 @@
private ScheduledExecutorService eventMapTriggerExecutor;
+ private static final String BRIDGE_NAME = "/bridgeName";
+
@Activate
public void activate() {
log.info("Activated");
@@ -77,108 +81,117 @@
* Registers workflows.
*/
private void registerWorkflows() {
- // registering class-loader
- workflowStore.registerLocal(this.getClass().getClassLoader());
+ try {
+ // registering class-loader
+ workflowStore.registerLocal(this.getClass().getClassLoader());
- // registering new workflow definition
- URI uri = URI.create("of-overlay.workflow-nova");
- Workflow 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.CreateOverlayBridge.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);
+ // registering new workflow definition
+ URI uri = URI.create("of-overlay.workflow-nova");
+ Workflow 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(DefaultWorkletDescription.builder().name(Ovs.CreateBridge.class.getName())
+ .staticDataModel(BRIDGE_NAME, "br-int")
+ .build())
+ .chain(Ovs.UpdateUnderlayBridgeId.class.getName())
+ .chain(DefaultWorkletDescription.builder().name(Ovs.CreateBridge.class.getName())
+ .staticDataModel(BRIDGE_NAME, "br-phy")
+ .build())
+ .chain(Ovs.CreateOverlayBridgeVxlanPort.class.getName())
+ .chain(Ovs.AddPhysicalPortsOnUnderlayBridge.class.getName())
+ .chain(Ovs.ConfigureUnderlayBridgeLocalIp.class.getName())
+ .build();
- // 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);
+ workflowStore.register(workflow);
- uri = URI.create("of-overlay.clean-workflow-nova");
- workflow = ImmutableListWorkflow.builder()
- .id(uri)
- //.attribute(WorkflowAttribute.REMOVE_AFTER_COMPLETE)
- .chain(Ovs.DeleteOverlayBridgeConfig.class.getName())
- .chain(Ovs.RemoveOverlayBridgeOfDevice.class.getName())
- .chain(Ovs.DeleteUnderlayBridgeConfig.class.getName())
- .chain(Ovs.RemoveUnderlayBridgeOfDevice.class.getName())
- .chain(Ovs.RemoveOvsdbDevice.class.getName())
- .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-waitAll-Bridge-Del");
- workflow = ImmutableListWorkflow.builder()
- .id(uri)
- //.attribute(WorkflowAttribute.REMOVE_AFTER_COMPLETE)
- .chain(Ovs.DeleteOverlayBridgeConfig.class.getName())
- .chain(Ovs.DeleteUnderlayBridgeConfig.class.getName())
- .chain(Ovs.RemoveBridgeOfDevice.class.getName())
- .chain(Ovs.RemoveOvsdbDevice.class.getName())
- .build();
- workflowStore.register(workflow);
+ uri = URI.create("of-overlay.clean-workflow-nova");
+ workflow = ImmutableListWorkflow.builder()
+ .id(uri)
+ //.attribute(WorkflowAttribute.REMOVE_AFTER_COMPLETE)
+ .chain(Ovs.DeleteOverlayBridgeConfig.class.getName())
+ .chain(Ovs.RemoveOverlayBridgeOfDevice.class.getName())
+ .chain(Ovs.DeleteUnderlayBridgeConfig.class.getName())
+ .chain(Ovs.RemoveUnderlayBridgeOfDevice.class.getName())
+ .chain(Ovs.RemoveOvsdbDevice.class.getName())
+ .build();
+ workflowStore.register(workflow);
- uri = URI.create("of-overlay.workflow-ovs-leaf");
- workflow = ImmutableListWorkflow.builder()
- .id(uri)
- .chain(Ovs.CreateOvsdbDevice.class.getName())
- .chain(Ovs.UpdateOvsVersion.class.getName())
- .chain(Ovs.UpdateUnderlayBridgeId.class.getName())
- .chain(Ovs.CreateUnderlayBridge.class.getName())
- .chain(Ovs.AddPhysicalPortsOnUnderlayBridge.class.getName())
- .build();
- workflowStore.register(workflow);
+ uri = URI.create("of-overlay.clean-workflow-nova-waitAll-Bridge-Del");
+ workflow = ImmutableListWorkflow.builder()
+ .id(uri)
+ //.attribute(WorkflowAttribute.REMOVE_AFTER_COMPLETE)
+ .chain(Ovs.DeleteOverlayBridgeConfig.class.getName())
+ .chain(Ovs.DeleteUnderlayBridgeConfig.class.getName())
+ .chain(Ovs.RemoveBridgeOfDevice.class.getName())
+ .chain(Ovs.RemoveOvsdbDevice.class.getName())
+ .build();
+ workflowStore.register(workflow);
- uri = URI.create("of-overlay.workflow-ovs-spine");
- workflow = ImmutableListWorkflow.builder()
- .id(uri)
- .chain(Ovs.CreateOvsdbDevice.class.getName())
- .chain(Ovs.UpdateOvsVersion.class.getName())
- .chain(Ovs.UpdateUnderlayBridgeId.class.getName())
- .chain(Ovs.CreateUnderlayBridge.class.getName())
- .chain(Ovs.AddPhysicalPortsOnUnderlayBridge.class.getName())
- .build();
- workflowStore.register(workflow);
+ uri = URI.create("of-overlay.workflow-ovs-leaf");
+ workflow = ImmutableListWorkflow.builder()
+ .id(uri)
+ .chain(Ovs.CreateOvsdbDevice.class.getName())
+ .chain(Ovs.UpdateOvsVersion.class.getName())
+ .chain(Ovs.UpdateUnderlayBridgeId.class.getName())
+ .chain(Ovs.CreateUnderlayBridge.class.getName())
+ .chain(Ovs.AddPhysicalPortsOnUnderlayBridge.class.getName())
+ .build();
+ workflowStore.register(workflow);
- deviceService.addListener(
- event -> {
- // trigger EventTask for DeviceEvent
- eventMapTriggerExecutor.submit(
- () -> workflowExecutionService.eventMapTrigger(
- event,
- // event hint supplier
- (ev) -> {
- if (ev == null || ev.subject() == null) {
- return null;
+ uri = URI.create("of-overlay.workflow-ovs-spine");
+ workflow = ImmutableListWorkflow.builder()
+ .id(uri)
+ .chain(Ovs.CreateOvsdbDevice.class.getName())
+ .chain(Ovs.UpdateOvsVersion.class.getName())
+ .chain(Ovs.UpdateUnderlayBridgeId.class.getName())
+ .chain(Ovs.CreateUnderlayBridge.class.getName())
+ .chain(Ovs.AddPhysicalPortsOnUnderlayBridge.class.getName())
+ .build();
+ workflowStore.register(workflow);
+
+ deviceService.addListener(
+ event -> {
+ // trigger EventTask for DeviceEvent
+ eventMapTriggerExecutor.submit(
+ () -> workflowExecutionService.eventMapTrigger(
+ event,
+ // event hint supplier
+ (ev) -> {
+ if (ev == null || ev.subject() == null) {
+ return null;
+ }
+ String hint = event.subject().id().toString();
+ log.debug("hint: {}", hint);
+ return hint;
}
- String hint = event.subject().id().toString();
- log.debug("hint: {}", hint);
- return hint;
- }
- )
- );
- }
- );
+ )
+ );
+ }
+ );
+ } catch (WorkflowException e) {
+ e.printStackTrace();
+ }
}
}
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 ad56d52..ccbc182 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
@@ -59,6 +59,7 @@
import org.onosproject.workflow.api.JsonDataModel;
import org.onosproject.workflow.api.WorkflowContext;
import org.onosproject.workflow.api.WorkflowException;
+import org.onosproject.workflow.api.StaticDataModel;
import org.onosproject.workflow.model.accessinfo.SshAccessInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -83,6 +84,7 @@
private static final Logger log = LoggerFactory.getLogger(Ovs.class);
private static final String MODEL_MGMT_IP = "/mgmtIp";
+ private static final String BRIDGE_NAME = "/bridgeName";
private static final String MODEL_OVSDB_PORT = "/ovsdbPort";
private static final String MODEL_OVS_VERSION = "/ovsVersion";
private static final String MODEL_OVS_DATAPATH_TYPE = "/ovsDatapathType";
@@ -535,6 +537,108 @@
}
}
+
+ public static class CreateBridge extends AbstractWorklet {
+
+ @StaticDataModel(path = BRIDGE_NAME)
+ String bridgeName;
+
+ @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 strOfDevId;
+
+ @Override
+ public boolean isNext(WorkflowContext context) throws WorkflowException {
+
+ check(strOfDevId != null, "invalid strOfDevIdUnderlay");
+ return !OvsUtil.isAvailableBridge(context, DeviceId.deviceId(strOfDevId));
+ }
+
+ @Override
+ public void process(WorkflowContext context) throws WorkflowException {
+
+ check(strOfDevId != null, "invalid strOfDevIdOverlay");
+ BridgeConfig bridgeConfig = OvsUtil.getOvsdbBehaviour(context, strMgmtIp, BridgeConfig.class);
+ List<ControllerInfo> ofControllers = OvsUtil.getOpenflowControllerInfoList(context);
+ DeviceId ofDeviceId = DeviceId.deviceId(strOfDevId);
+
+ if (ofControllers == null || ofControllers.size() == 0) {
+ throw new WorkflowException("Invalid of controllers");
+ }
+
+ Optional<BridgeDescription> optBd = OvsUtil.getBridgeDescription(bridgeConfig, bridgeName);
+ if (!optBd.isPresent()) {
+
+ // If bridge does not exist, just creates a new bridge.
+ context.waitCompletion(DeviceEvent.class, ofDeviceId.toString(),
+ () -> OvsUtil.createBridge(bridgeConfig,
+ bridgeName,
+ 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({})", bridgeName, 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.
+ context.waitCompletion(DeviceEvent.class, ofDeviceId.toString(),
+ () -> 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 creating overlay openflow bridge.
*/