blob: 20b37711dca94aba4ab23a7e3d0f7529ee9e1452 [file] [log] [blame]
/*
* Copyright 2018-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.impl.example;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.JsonNodeType;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onosproject.net.device.DeviceService;
import org.onosproject.workflow.api.AbstractWorklet;
import org.onosproject.workflow.api.DataModelTree;
import org.onosproject.workflow.api.ImmutableListWorkflow;
import org.onosproject.workflow.api.JsonDataModelTree;
import org.onosproject.workflow.api.Workflow;
import org.onosproject.workflow.api.WorkflowContext;
import org.onosproject.workflow.api.WorkflowException;
import org.onosproject.workflow.api.WorkflowExecutionService;
import org.onosproject.workflow.api.WorkflowStore;
import org.onosproject.workflow.api.WorkplaceStore;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.URI;
/**
* Class for sample workflow.
*/
@Component(immediate = true)
public class SampleWorkflow {
private static final Logger log = LoggerFactory.getLogger(SampleWorkflow.class);
@Reference(cardinality = ReferenceCardinality.MANDATORY)
protected WorkflowStore workflowStore;
@Reference(cardinality = ReferenceCardinality.MANDATORY)
protected WorkplaceStore workplaceStore;
@Reference(cardinality = ReferenceCardinality.MANDATORY)
protected WorkflowExecutionService workflowExecutionService;
@Reference(cardinality = ReferenceCardinality.MANDATORY)
protected DeviceService deviceService;
@Activate
public void activate() {
log.info("Activated");
registerWorkflows();
}
@Deactivate
public void deactivate() {
log.info("Deactivated");
}
/**
* Registers example workflows.
*/
private void registerWorkflows() {
// registering class-loader
workflowStore.registerLocal(this.getClass().getClassLoader());
// registering new workflow definition
URI uri = URI.create("sample.workflow-0");
Workflow workflow = ImmutableListWorkflow.builder()
.id(uri)
.chain(SampleWorklet1.class.getName())
.chain(SampleWorklet2.class.getName())
.chain(SampleWorklet3.class.getName())
.chain(SampleWorklet4.class.getName())
.chain(SampleWorklet5.class.getName())
.build();
workflowStore.register(workflow);
// registering new workflow definition
uri = URI.create("sample.workflow-1");
workflow = ImmutableListWorkflow.builder()
.id(uri)
.chain(SampleWorklet3.class.getName())
.chain(SampleWorklet2.class.getName())
.chain(SampleWorklet1.class.getName())
.chain(SampleWorklet4.class.getName())
.chain(SampleWorklet5.class.getName())
.build();
workflowStore.register(workflow);
// registering new workflow definition
uri = URI.create("sample.workflow-2");
workflow = ImmutableListWorkflow.builder()
.id(uri)
.chain(SampleWorklet1.class.getName())
.chain(SampleWorklet3.class.getName())
.chain(SampleWorklet2.class.getName())
.chain(SampleWorklet4.class.getName())
.chain(SampleWorklet5.class.getName())
.build();
workflowStore.register(workflow);
}
/**
* Abstract class for sample worklet.
*/
public abstract static class AbsSampleWorklet extends AbstractWorklet {
protected static final String SAMPLE_DATAMODEL_PTR = "/sample/job";
/**
* Constructor for sample worklet.
*/
protected AbsSampleWorklet() {
}
/**
* Allocates or gets data model.
* @param context workflow context
* @return json object node
* @throws WorkflowException workflow exception
*/
protected ObjectNode allocOrGetModel(WorkflowContext context) throws WorkflowException {
JsonDataModelTree tree = (JsonDataModelTree) context.data();
JsonNode params = tree.root();
if (params.at(SAMPLE_DATAMODEL_PTR).getNodeType() == JsonNodeType.MISSING) {
tree.alloc(SAMPLE_DATAMODEL_PTR, DataModelTree.Nodetype.MAP);
}
return (ObjectNode) params.at(SAMPLE_DATAMODEL_PTR);
}
/**
* Gets data model.
* @param context workflow context
* @return json object node
* @throws WorkflowException workflow exception
*/
protected ObjectNode getDataModel(WorkflowContext context) throws WorkflowException {
DataModelTree tree = context.data();
return ((JsonDataModelTree) tree.subtree(SAMPLE_DATAMODEL_PTR)).rootObject();
}
/**
* Sleeps for 'ms' milli seconds.
* @param ms milli seconds to sleep
*/
protected void sleep(long ms) {
try {
Thread.sleep(ms);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
/**
* Class for sample worklet-1.
*/
public static class SampleWorklet1 extends AbsSampleWorklet {
@Override
public void process(WorkflowContext context) throws WorkflowException {
ObjectNode node = getDataModel(context);
node.put("work1", "done");
log.info("workflow-process {}-{}", context.workplaceName(), this.getClass().getSimpleName());
sleep(30);
context.completed(); //Complete the job of worklet in the process
}
@Override
public boolean isNext(WorkflowContext context) throws WorkflowException {
ObjectNode node = allocOrGetModel(context);
log.info("workflow-isNext {}-{}", context.workplaceName(), this.getClass().getSimpleName());
sleep(30);
return !node.has("work1");
}
}
/**
* Class for sample worklet-2 (using timeout).
*/
public static class SampleWorklet2 extends AbsSampleWorklet {
@Override
public void process(WorkflowContext context) throws WorkflowException {
ObjectNode node = getDataModel(context);
node.put("work2", "done");
log.info("workflow-process {}-{}", context.workplaceName(), this.getClass().getSimpleName());
sleep(50);
context.waitFor(50L); //Timeout will happen after 50 milli seconds.
}
@Override
public void timeout(WorkflowContext context) throws WorkflowException {
context.completed(); //Complete the job of worklet by timeout
}
@Override
public boolean isNext(WorkflowContext context) throws WorkflowException {
ObjectNode node = allocOrGetModel(context);
log.info("workflow-isNext {}-{}", context.workplaceName(), this.getClass().getSimpleName());
sleep(50);
return !node.has("work2");
}
}
public static class SampleWorklet3 extends AbsSampleWorklet {
@Override
public void process(WorkflowContext context) throws WorkflowException {
ObjectNode node = getDataModel(context);
node.put("work3", "done");
log.info("workflow-process {}-{}", context.workplaceName(), this.getClass().getSimpleName());
sleep(10);
context.completed();
}
@Override
public boolean isNext(WorkflowContext context) throws WorkflowException {
ObjectNode node = allocOrGetModel(context);
log.info("workflow-isNext {}-{}", context.workplaceName(), this.getClass().getSimpleName());
sleep(10);
return !node.has("work3");
}
}
public static class SampleWorklet4 extends AbsSampleWorklet {
@Override
public void process(WorkflowContext context) throws WorkflowException {
ObjectNode node = getDataModel(context);
node.put("work4", "done");
log.info("workflow-process {}-{}", context.workplaceName(), this.getClass().getSimpleName());
sleep(10);
context.completed();
}
@Override
public boolean isNext(WorkflowContext context) throws WorkflowException {
ObjectNode node = allocOrGetModel(context);
log.info("workflow-isNext {}-{}", context.workplaceName(), this.getClass().getSimpleName());
sleep(10);
return !node.has("work4");
}
}
public static class SampleWorklet5 extends AbsSampleWorklet {
@Override
public void process(WorkflowContext context) throws WorkflowException {
ObjectNode node = getDataModel(context);
node.put("work5", "done");
log.info("workflow-process {}-{}", context.workplaceName(), this.getClass().getSimpleName());
sleep(10);
context.completed();
}
@Override
public boolean isNext(WorkflowContext context) throws WorkflowException {
ObjectNode node = allocOrGetModel(context);
log.info("workflow-isNext {}-{}", context.workplaceName(), this.getClass().getSimpleName());
sleep(10);
return !node.has("work5");
}
}
}