Workflow LCM worklets
Workflow LCM would have default worklets in the framework
1) Branch worklet :- Then decision-making worklet determines whether to execute the current worklet or not
2) Sleep worklet :- Pause the execution of the current workflow process.
Change-Id: Ia0dfae6043f74169dda4f511b861b80bd50d5697
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/AbstractBranchWorklet.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/AbstractBranchWorklet.java
new file mode 100644
index 0000000..025aaf9
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/AbstractBranchWorklet.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2024-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.workflow.api;
+
+import static org.onosproject.workflow.api.CheckCondition.check;
+
+/**
+ * Abstract class representing branch work-let. Branch work-let is used for branching workflow execution.
+ */
+public abstract class AbstractBranchWorklet extends AbstractWorklet {
+
+ public static final String BRANCH_LABEL_PATH = "/branch-target-label-data-path";
+
+ @StaticDataModel(path = BRANCH_LABEL_PATH)
+ String branchLabel;
+
+ @Override
+ public void process(WorkflowContext context) throws WorkflowException {
+ throw new WorkflowException("This workletType.process should not be called");
+ }
+
+ /**
+ * Checks the condition for branch.
+ * @param context workflow context
+ * @return true is branch, false is not-branch(passing branch)
+ * @throws WorkflowException workflow exception
+ */
+ public abstract boolean isBranch(WorkflowContext context) throws WorkflowException;
+
+ public Label getBranchLabel() throws WorkflowException {
+ check(branchLabel != null, "Invalid branch label string(" + branchLabel + ")");
+ return Label.as(branchLabel);
+ }
+}
+
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/AbstractWorklet.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/AbstractWorklet.java
index b9fb133..d3c205f 100644
--- a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/AbstractWorklet.java
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/AbstractWorklet.java
@@ -34,7 +34,7 @@
}
@Override
- public boolean isNext(WorkflowContext context) throws WorkflowException {
+ public boolean needsProcess(WorkflowContext context) throws WorkflowException {
throw new WorkflowException("(" + tag() + ").isNext should not be called");
}
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/BranchWorklet.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/BranchWorklet.java
index 4f91bba..450d0b9 100644
--- a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/BranchWorklet.java
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/BranchWorklet.java
@@ -26,7 +26,7 @@
}
@Override
- default boolean isNext(WorkflowContext context) throws WorkflowException {
+ default boolean needsProcess(WorkflowContext context) throws WorkflowException {
throw new WorkflowException("This workletType.isNext should not be called");
}
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/ImmutableListWorkflow.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/ImmutableListWorkflow.java
index 1a77e25..1965c43 100644
--- a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/ImmutableListWorkflow.java
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/ImmutableListWorkflow.java
@@ -132,7 +132,7 @@
staticDataModelInjector.inject(worklet, workletDesc);
}
}
- if (worklet.isNext(context)) {
+ if (worklet.needsProcess(context)) {
return pc;
}
}
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/Label.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/Label.java
new file mode 100644
index 0000000..e816177
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/Label.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2024-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.workflow.api;
+
+import com.google.common.base.MoreObjects;
+
+import java.util.Objects;
+
+/**
+ * A label indicating the specific PC.
+ */
+public final class Label {
+
+ /**
+ * The name of label.
+ */
+ private String name;
+
+ /**
+ * The constructor of Label.
+ * @param name The name of label
+ */
+ private Label(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Returns the name of label.
+ * @return name of label
+ */
+ public String name() {
+ return this.name;
+ }
+
+ /**
+ * Label builder.
+ * @param name The name of label
+ * @return A label
+ */
+ public static Label as(String name) {
+ return new Label(name);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(name);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return Objects.equals(name, ((Label) obj).name);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("name", name)
+ .toString();
+ }
+}
+
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/SleepWorklet.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/SleepWorklet.java
new file mode 100644
index 0000000..d61e5b6
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/SleepWorklet.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2024-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.workflow.api;
+
+import org.slf4j.Logger;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+public class SleepWorklet extends AbstractWorklet {
+
+ // Path for duration of sleep in msec.
+ public static final String SLEEP_MSEC_PATH = "/sleep-msec-data-path";
+
+ @StaticDataModel(path = SLEEP_MSEC_PATH)
+ Integer time;
+
+ protected static final Logger log = getLogger(SleepWorklet.class);
+
+ @Override
+ public boolean needsProcess(WorkflowContext context) throws WorkflowException {
+ return true;
+ }
+
+ @Override
+ public void process(WorkflowContext context) throws WorkflowException {
+ log.info("Workflow-process: {}@{} ",
+ this.getClass().getSimpleName(), context.workplaceName());
+ context.waitFor(time);
+ }
+
+ @Override
+ public void timeout(WorkflowContext context) throws WorkflowException {
+ log.info("sleep worklet timeout happened");
+ context.completed(); //Complete the job of worklet by timeout
+ }
+}
+
+
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/Worklet.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/Worklet.java
index c4b4fb2..bda518c 100644
--- a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/Worklet.java
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/Worklet.java
@@ -44,7 +44,7 @@
* @return true means this worklet is the next worklet to be processed
* @throws WorkflowException workflow exception
*/
- boolean isNext(WorkflowContext context) throws WorkflowException;
+ boolean needsProcess(WorkflowContext context) throws WorkflowException;
/**
* Checks whether is this worklet completed or not. 'isCompleted' checking is triggered by an event task.
@@ -82,7 +82,7 @@
}
@Override
- public boolean isNext(WorkflowContext context) throws WorkflowException {
+ public boolean needsProcess(WorkflowContext context) throws WorkflowException {
throw new WorkflowException("(" + tag() + ").isNext should not be called");
}
@@ -112,7 +112,7 @@
}
@Override
- public boolean isNext(WorkflowContext context) throws WorkflowException {
+ public boolean needsProcess(WorkflowContext context) throws WorkflowException {
throw new WorkflowException("(" + tag() + ").isNext should not be called");
}
@@ -142,7 +142,7 @@
}
@Override
- public boolean isNext(WorkflowContext context) throws WorkflowException {
+ public boolean needsProcess(WorkflowContext context) throws WorkflowException {
throw new WorkflowException("(" + tag() + ").isNext should not be called");
}
diff --git a/apps/workflow/app/src/main/java/org/onosproject/workflow/impl/WorkplaceWorkflow.java b/apps/workflow/app/src/main/java/org/onosproject/workflow/impl/WorkplaceWorkflow.java
index 1dbd5d5..e95adc7 100644
--- a/apps/workflow/app/src/main/java/org/onosproject/workflow/impl/WorkplaceWorkflow.java
+++ b/apps/workflow/app/src/main/java/org/onosproject/workflow/impl/WorkplaceWorkflow.java
@@ -97,7 +97,7 @@
public static class CreateWorkplace extends AbsWorkflowWorklet {
@Override
- public boolean isNext(WorkflowContext context) throws WorkflowException {
+ public boolean needsProcess(WorkflowContext context) throws WorkflowException {
WorkflowDescription wfDesc = getWorkflowDesc(context);
@@ -146,7 +146,7 @@
@Override
public void timeout(WorkflowContext context) throws WorkflowException {
- if (!isNext(context)) {
+ if (!needsProcess(context)) {
context.completed(); //Complete the job of worklet by timeout
} else {
super.timeout(context);
@@ -175,7 +175,7 @@
}
@Override
- public boolean isNext(WorkflowContext context) throws WorkflowException {
+ public boolean needsProcess(WorkflowContext context) throws WorkflowException {
WorkflowDescription wfDesc = getWorkflowDesc(context);
diff --git a/apps/workflow/app/src/main/java/org/onosproject/workflow/impl/example/SampleWorkflow.java b/apps/workflow/app/src/main/java/org/onosproject/workflow/impl/example/SampleWorkflow.java
index 529bfb0..164f0ea 100644
--- a/apps/workflow/app/src/main/java/org/onosproject/workflow/impl/example/SampleWorkflow.java
+++ b/apps/workflow/app/src/main/java/org/onosproject/workflow/impl/example/SampleWorkflow.java
@@ -220,7 +220,7 @@
}
@Override
- public boolean isNext(WorkflowContext context) throws WorkflowException {
+ public boolean needsProcess(WorkflowContext context) throws WorkflowException {
ObjectNode node = allocOrGetModel(context);
log.info("workflow-isNext {}-{}", context.workplaceName(), this.getClass().getSimpleName());
sleep(30);
@@ -255,7 +255,7 @@
}
@Override
- public boolean isNext(WorkflowContext context) throws WorkflowException {
+ public boolean needsProcess(WorkflowContext context) throws WorkflowException {
ObjectNode node = allocOrGetModel(context);
log.info("workflow-isNext {}-{}", context.workplaceName(), this.getClass().getSimpleName());
sleep(50);
@@ -280,7 +280,7 @@
}
@Override
- public boolean isNext(WorkflowContext context) throws WorkflowException {
+ public boolean needsProcess(WorkflowContext context) throws WorkflowException {
ObjectNode node = allocOrGetModel(context);
log.info("workflow-isNext {}-{}", context.workplaceName(), this.getClass().getSimpleName());
sleep(10);
@@ -304,7 +304,7 @@
}
@Override
- public boolean isNext(WorkflowContext context) throws WorkflowException {
+ public boolean needsProcess(WorkflowContext context) throws WorkflowException {
ObjectNode node = allocOrGetModel(context);
log.info("workflow-isNext {}-{}", context.workplaceName(), this.getClass().getSimpleName());
sleep(10);
@@ -328,7 +328,7 @@
}
@Override
- public boolean isNext(WorkflowContext context) throws WorkflowException {
+ public boolean needsProcess(WorkflowContext context) throws WorkflowException {
ObjectNode node = allocOrGetModel(context);
log.info("workflow-isNext {}-{}", context.workplaceName(), this.getClass().getSimpleName());
sleep(10);
@@ -354,7 +354,7 @@
}
@Override
- public boolean isNext(WorkflowContext context) throws WorkflowException {
+ public boolean needsProcess(WorkflowContext context) throws WorkflowException {
ObjectNode node = allocOrGetModel(context);
log.info("workflow-isNext {}-{}", context.workplaceName(), this.getClass().getSimpleName());
sleep(10);
@@ -381,7 +381,7 @@
}
@Override
- public boolean isNext(WorkflowContext context) throws WorkflowException {
+ public boolean needsProcess(WorkflowContext context) throws WorkflowException {
ObjectNode node = allocOrGetModel(context);
log.info("workflow-isNext {}-{}", context.workplaceName(), this.getClass().getSimpleName());
sleep(10);
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 923173c..ed56610 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
@@ -383,7 +383,7 @@
Integer intOvsdbPort;
@Override
- public boolean isNext(WorkflowContext context) throws WorkflowException {
+ public boolean needsProcess(WorkflowContext context) throws WorkflowException {
OvsdbClientService ovsdbClient = OvsUtil.getOvsdbClient(context, strMgmtIp, intOvsdbPort);
return ovsdbClient == null || !ovsdbClient.isConnected();
@@ -419,7 +419,7 @@
@Override
public void timeout(WorkflowContext context) throws WorkflowException {
- if (!isNext(context)) {
+ if (!needsProcess(context)) {
context.completed(); //Complete the job of worklet by timeout
} else {
super.timeout(context);
@@ -437,7 +437,7 @@
String strMgmtIp;
@Override
- public boolean isNext(WorkflowContext context) throws WorkflowException {
+ public boolean needsProcess(WorkflowContext context) throws WorkflowException {
DeviceId devId = DeviceId.deviceId(OVSDB_DEVICE_PREFIX.concat(strMgmtIp));
@@ -466,7 +466,7 @@
DeviceEvent deviceEvent = (DeviceEvent) event;
switch (deviceEvent.type()) {
case DEVICE_REMOVED:
- return !isNext(context);
+ return !needsProcess(context);
default:
return false;
}
@@ -474,7 +474,7 @@
@Override
public void timeout(WorkflowContext context) throws WorkflowException {
- if (!isNext(context)) {
+ if (!needsProcess(context)) {
context.completed(); //Complete worklet by timeout
} else {
super.timeout(context);
@@ -494,7 +494,7 @@
JsonNode strSshAccessInfo;
@Override
- public boolean isNext(WorkflowContext context) throws WorkflowException {
+ public boolean needsProcess(WorkflowContext context) throws WorkflowException {
return strOvsVersion == null;
}
@@ -527,7 +527,7 @@
ObjectNode strOfDevId;
@Override
- public boolean isNext(WorkflowContext context) throws WorkflowException {
+ public boolean needsProcess(WorkflowContext context) throws WorkflowException {
return strOfDevId == null;
}
@@ -586,7 +586,7 @@
ObjectNode strOfDevId;
@Override
- public boolean isNext(WorkflowContext context) throws WorkflowException {
+ public boolean needsProcess(WorkflowContext context) throws WorkflowException {
check(strOfDevId != null, "invalid strOfDevIdUnderlay");
String bridgeId = strOfDevId.get(bridgeName).asText();
@@ -661,7 +661,7 @@
@Override
public void timeout(WorkflowContext context) throws WorkflowException {
- if (!isNext(context)) {
+ if (!needsProcess(context)) {
context.completed(); //Complete the job of worklet by timeout
} else {
super.timeout(context);
@@ -688,7 +688,7 @@
ObjectNode strOfDevIdOverlay;
@Override
- public boolean isNext(WorkflowContext context) throws WorkflowException {
+ public boolean needsProcess(WorkflowContext context) throws WorkflowException {
check(strOfDevIdOverlay != null, "invalid strOfDevIdOverlay");
String bridge = strOfDevIdOverlay.get(BRIDGE_OVERLAY).asText();
@@ -766,7 +766,7 @@
@Override
public void timeout(WorkflowContext context) throws WorkflowException {
- if (!isNext(context)) {
+ if (!needsProcess(context)) {
context.completed(); //Complete the job of worklet by timeout
} else {
super.timeout(context);
@@ -788,7 +788,7 @@
private static final String OVS_VXLAN_PORTNAME = "vxlan";
@Override
- public boolean isNext(WorkflowContext context) throws WorkflowException {
+ public boolean needsProcess(WorkflowContext context) throws WorkflowException {
check(strOfDevIdOverlay != null, "invalid strOfDevIdOverlay");
String bridge = strOfDevIdOverlay.get(BRIDGE_OVERLAY).asText();
@@ -835,7 +835,7 @@
DeviceEvent deviceEvent = (DeviceEvent) event;
switch (deviceEvent.type()) {
case PORT_ADDED:
- return !isNext(context);
+ return !needsProcess(context);
default:
return false;
}
@@ -843,7 +843,7 @@
@Override
public void timeout(WorkflowContext context) throws WorkflowException {
- if (!isNext(context)) {
+ if (!needsProcess(context)) {
context.completed(); //Complete the job of worklet by timeout
} else {
super.timeout(context);
@@ -872,7 +872,7 @@
ArrayNode arrNodePhysicalPorts;
@Override
- public boolean isNext(WorkflowContext context) throws WorkflowException {
+ public boolean needsProcess(WorkflowContext context) throws WorkflowException {
check(strOfDevIdUnderlay != null, "invalid strOfDevIdUnderlay");
String bridge = strOfDevIdUnderlay.get(BRIDGE_UNDERLAY).asText();
DeviceId brphyDevId = DeviceId.deviceId(bridge);
@@ -899,7 +899,7 @@
DeviceEvent deviceEvent = (DeviceEvent) event;
switch (deviceEvent.type()) {
case PORT_ADDED:
- return !isNext(context);
+ return !needsProcess(context);
default:
return false;
}
@@ -907,7 +907,7 @@
@Override
public void timeout(WorkflowContext context) throws WorkflowException {
- if (!isNext(context)) {
+ if (!needsProcess(context)) {
context.completed(); //Complete the job of worklet by timeout
} else {
super.timeout(context);
@@ -990,7 +990,7 @@
String strVtepIp;
@Override
- public boolean isNext(WorkflowContext context) throws WorkflowException {
+ public boolean needsProcess(WorkflowContext context) throws WorkflowException {
SshAccessInfo sshAccessInfo = SshAccessInfo.valueOf(strSshAccessInfo);
check(Objects.nonNull(sshAccessInfo), "Invalid ssh access info " + context.data());
@@ -1034,7 +1034,7 @@
String strMgmtIp;
@Override
- public boolean isNext(WorkflowContext context) throws WorkflowException {
+ public boolean needsProcess(WorkflowContext context) throws WorkflowException {
BridgeConfig bridgeConfig = OvsUtil.getOvsdbBehaviour(context, strMgmtIp, BridgeConfig.class);
@@ -1051,7 +1051,7 @@
bridgeConfig.deleteBridge(BridgeName.bridgeName(BRIDGE_OVERLAY));
for (int i = 0; i < 10; i++) {
- if (!isNext(context)) {
+ if (!needsProcess(context)) {
context.completed();
return;
}
@@ -1078,7 +1078,7 @@
String strMgmtIp;
@Override
- public boolean isNext(WorkflowContext context) throws WorkflowException {
+ public boolean needsProcess(WorkflowContext context) throws WorkflowException {
DeviceId devId = OvsUtil.buildOfDeviceId(IpAddress.valueOf(strMgmtIp), DEVID_IDX_BRIDGE_OVERLAY);
@@ -1107,7 +1107,7 @@
DeviceEvent deviceEvent = (DeviceEvent) event;
switch (deviceEvent.type()) {
case DEVICE_REMOVED:
- return !isNext(context);
+ return !needsProcess(context);
default:
return false;
}
@@ -1115,7 +1115,7 @@
@Override
public void timeout(WorkflowContext context) throws WorkflowException {
- if (!isNext(context)) {
+ if (!needsProcess(context)) {
context.completed(); //Complete the job of worklet by timeout
} else {
super.timeout(context);
@@ -1132,7 +1132,7 @@
String strMgmtIp;
@Override
- public boolean isNext(WorkflowContext context) throws WorkflowException {
+ public boolean needsProcess(WorkflowContext context) throws WorkflowException {
BridgeConfig bridgeConfig = OvsUtil.getOvsdbBehaviour(context, strMgmtIp, BridgeConfig.class);
@@ -1149,7 +1149,7 @@
bridgeConfig.deleteBridge(BridgeName.bridgeName(BRIDGE_UNDERLAY));
for (int i = 0; i < 10; i++) {
- if (!isNext(context)) {
+ if (!needsProcess(context)) {
context.completed();
return;
}
@@ -1176,7 +1176,7 @@
String strMgmtIp;
@Override
- public boolean isNext(WorkflowContext context) throws WorkflowException {
+ public boolean needsProcess(WorkflowContext context) throws WorkflowException {
DeviceId devId = OvsUtil.buildOfDeviceId(IpAddress.valueOf(strMgmtIp), DEVID_IDX_BRIDGE_UNDERLAY_NOVA);
@@ -1205,7 +1205,7 @@
DeviceEvent deviceEvent = (DeviceEvent) event;
switch (deviceEvent.type()) {
case DEVICE_REMOVED:
- return !isNext(context);
+ return !needsProcess(context);
default:
return false;
}
@@ -1213,7 +1213,7 @@
@Override
public void timeout(WorkflowContext context) throws WorkflowException {
- if (!isNext(context)) {
+ if (!needsProcess(context)) {
context.completed(); //Complete the job of worklet by timeout
} else {
super.timeout(context);
@@ -1233,7 +1233,7 @@
ObjectNode ofDevId;
@Override
- public boolean isNext(WorkflowContext context) throws WorkflowException {
+ public boolean needsProcess(WorkflowContext context) throws WorkflowException {
boolean isOfDevicePresent = true;
@@ -1297,7 +1297,7 @@
switch (deviceEvent.type()) {
case DEVICE_REMOVED:
log.trace("GOT DEVICE REMOVED EVENT FOR DEVICE {}", event.subject());
- return !isNext(context);
+ return !needsProcess(context);
default:
return false;
}
@@ -1305,7 +1305,7 @@
@Override
public void timeout(WorkflowContext context) throws WorkflowException {
- if (!isNext(context)) {
+ if (!needsProcess(context)) {
context.completed(); //Complete the job of worklet by timeout
} else {
super.timeout(context);