ONOS-7963 workflow invocation trigger on ONOS event

Change-Id: Ie9014bfa77f5514c3580042f9ff2add8e42f25f6
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/AbstractWorkflow.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/AbstractWorkflow.java
index 5fb8943..30e50db 100644
--- a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/AbstractWorkflow.java
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/AbstractWorkflow.java
@@ -57,4 +57,5 @@
                 .data(data)
                 .build();
     }
+
 }
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/ContextEventMapStore.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/ContextEventMapStore.java
index 4b54cf3..389352c 100644
--- a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/ContextEventMapStore.java
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/ContextEventMapStore.java
@@ -33,11 +33,21 @@
      * @param eventType the class name of event
      * @param eventHintSet Set of event hint string value of the event
      * @param contextName workflow context name
-     * @param programCounterString the program counter of workflow
+     * @param programCounter the program counter of workflow
      * @throws WorkflowException workflow exception
      */
     void registerEventMap(String eventType, Set<String> eventHintSet,
-                          String contextName, String programCounterString) throws WorkflowException;
+                          String contextName, ProgramCounter programCounter) throws WorkflowException;
+
+    /**
+     * Registers workflow trigger flag.
+     * @param eventType the class name of event
+     * @param eventHintSet Set of event hint string value of the event
+     * @param contextName workflow context name
+     * @throws WorkflowException workflow exception
+     */
+    void registerTriggerFlag(String eventType, Set<String> eventHintSet,
+                                    String contextName) throws WorkflowException;
 
     /**
      * Unregisters workflow context event mapping.
@@ -52,10 +62,10 @@
      * Returns workflow context event mapping.
      * @param eventType the class name of event
      * @param eventHint vent hint string value of the event
-     * @return Map of workflow context and value (program counter)
+     * @return Map of workflow context and value (WorkflowEventMetaData)
      * @throws WorkflowException workflow exception
      */
-    Map<String, String> getEventMapByHint(String eventType,
+    Map<String, WorkflowEventMetaData> getEventMapByHint(String eventType,
                                           String eventHint) throws WorkflowException;
 
     /**
@@ -66,12 +76,23 @@
     boolean isEventMapPresent(String contextName);
 
     /**
+     * Returns true or false depending on trigger flag for the workflow.
+     * @param eventType the class name of event
+     * @param eventHint vent hint string value of the event
+     * @param contextName name of workflow context
+     * @return Boolean true or false depending on trigger flag for the workflow
+     * @throws WorkflowException workflow exception
+     */
+    boolean isTriggerSet(String eventType, String eventHint,
+                         String contextName) throws WorkflowException;
+
+    /**
      * Returns child nodes on document tree path.
      * @param path document tree path including eventType and Hint
      * @return children under document tree path
      * @throws WorkflowException workflow exception
      */
-    Map<String, Versioned<String>> getChildren(String path) throws WorkflowException;
+    Map<String, Versioned<WorkflowEventMetaData>> getChildren(String path) throws WorkflowException;
 
     /**
      * Returns document path.
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/DefaultWorkflowContext.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/DefaultWorkflowContext.java
index 8f5d3c7..977a978 100644
--- a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/DefaultWorkflowContext.java
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/DefaultWorkflowContext.java
@@ -92,6 +92,12 @@
     private transient WorkplaceStore workplaceStore;
 
     /**
+     * Service reference for eventMap store.
+     */
+    private transient ContextEventMapStore eventMapStore;
+
+
+    /**
      * Constructor of DefaultWorkflowContext.
      * @param builder default workflow context builder
      */
@@ -214,6 +220,11 @@
     }
 
     @Override
+    public void registerTriggerEvent(Class<? extends Event> event, Set<String> eventHintSet) throws WorkflowException {
+        eventMapStore.registerTriggerFlag(event.getName(), eventHintSet, this.name());
+    }
+
+    @Override
     public void setWorkflowExecutionService(WorkflowExecutionService workflowExecutionService) {
         this.workflowExecutionService = workflowExecutionService;
     }
@@ -243,6 +254,17 @@
         return workplaceStore;
     }
 
+
+    @Override
+    public void setEventMapStore(ContextEventMapStore contextEventMapStore) {
+        this.eventMapStore = contextEventMapStore;
+    }
+
+    @Override
+    public ContextEventMapStore eventMapStore() {
+        return eventMapStore;
+    }
+
     public <T> T getService(Class<T> serviceClass) throws WorkflowException {
         T service;
         try {
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 5819f11..f167b94 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
@@ -28,6 +28,7 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.Set;
 
 import static org.onosproject.workflow.api.CheckCondition.check;
@@ -55,6 +56,8 @@
     private static JsonDataModelInjector dataModelInjector = new JsonDataModelInjector();
     private static StaticDataModelInjector staticDataModelInjector = new StaticDataModelInjector();
 
+    private Optional<String> triggerWorkletClassName = Optional.empty();
+
     /**
      * Constructor of ImmutableListWorkflow.
      *
@@ -62,12 +65,18 @@
      */
     private ImmutableListWorkflow(Builder builder) {
         super(builder.id);
+        triggerWorkletClassName = builder.triggerWorkletClassName;
         this.initWorkletType = builder.initWorkletType;
         program = ImmutableList.copyOf(builder.workletDescList);
         attributes = ImmutableSet.copyOf(builder.attributes);
     }
 
     @Override
+    public Optional<String> getTriggerWorkletClassName() {
+        return triggerWorkletClassName;
+    }
+
+    @Override
     public Worklet init(WorkflowContext context) throws WorkflowException {
         if (Objects.isNull(initWorkletType)) {
             return null;
@@ -209,6 +218,12 @@
     }
 
     @Override
+    public Worklet getTriggerWorkletInstance(String workletType) throws WorkflowException {
+        return getWorkletInstance(workletType);
+    }
+
+
+    @Override
     public WorkletDescription getWorkletDesc(ProgramCounter pc) {
 
         WorkletDescription workletDescription = program.get(pc.workletIndex());
@@ -297,6 +312,7 @@
     public static class Builder {
 
         private URI id;
+        private Optional<String> triggerWorkletClassName = Optional.empty();
         private String initWorkletType;
         private final List<WorkletDescription> workletDescList = Lists.newArrayList();
         private final Set<WorkflowAttribute> attributes = Sets.newHashSet();
@@ -314,6 +330,17 @@
         }
 
         /**
+         * Sets trigger flag of immutable list workflow.
+         *
+         * @param triggerWorkletClassName name of trigger worklet class
+         * @return builder
+         */
+        public Builder trigger(String triggerWorkletClassName) {
+            this.triggerWorkletClassName = Optional.of(triggerWorkletClassName);
+            return this;
+        }
+
+        /**
          * Sets init worklet class name of immutable list workflow.
          *
          * @param workletClassName class name of worklet
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/TriggerWorklet.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/TriggerWorklet.java
new file mode 100644
index 0000000..3931693
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/TriggerWorklet.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2019-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.onosproject.event.Event;
+
+/**
+ * Abstract class for Trigger worklet.
+ */
+public abstract class TriggerWorklet implements Worklet {
+
+    @Override
+    public String tag() {
+        return this.getClass().getName();
+    }
+
+    /**
+     * Registers trigger event for a workflow under the workflow context.
+     * @param context workflow context
+     * @throws WorkflowException workflow exception
+     */
+    public abstract void register(WorkflowContext context) throws WorkflowException;
+
+    /**
+     * Validates trigger event for a given workflow context.
+     * @param context workflow context
+     * @param event trigger event
+     * @return true/false based on trigger event's validity
+     * @throws WorkflowException workflow exception
+     */
+    public abstract boolean isTriggerValid(WorkflowContext context, Event event) throws WorkflowException;
+
+    @Override
+    public boolean isCompleted(WorkflowContext context, Event event)throws WorkflowException {
+        throw new WorkflowException("(" + tag() + ").isCompleted should not be called");
+    }
+
+    @Override
+    public boolean isNext(WorkflowContext context) throws WorkflowException {
+        throw new WorkflowException("(" + tag() + ").isNext should not be called");
+    }
+
+    @Override
+    public void timeout(WorkflowContext context) throws WorkflowException {
+        throw new WorkflowException("(" + tag() + ").timeout should not be called");
+    }
+
+    @Override
+    public void process(WorkflowContext context) throws WorkflowException {
+        throw new WorkflowException("(" + tag() + ").process should not be called");
+    }
+}
+
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WfTriggerEventTask.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WfTriggerEventTask.java
new file mode 100644
index 0000000..8febd38
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WfTriggerEventTask.java
@@ -0,0 +1,124 @@
+/*
+ * 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.api;
+
+import com.google.common.base.MoreObjects;
+import org.onosproject.event.Event;
+
+import java.util.Objects;
+
+import static org.onosproject.workflow.api.CheckCondition.check;
+
+/**
+ * Class for WorkFlow Trigger event task.
+ */
+public final class WfTriggerEventTask extends HandlerTask {
+
+    /**
+     * Event triggering event task.
+     */
+    private final Event event;
+
+    /**
+     * Constructor of event task.
+     * @param builder builder of event task
+     */
+    private WfTriggerEventTask(Builder builder) {
+        super(builder);
+        this.event = builder.event;
+    }
+
+
+    /**
+     * Gets event of event task.
+     * @return event triggering event task
+     */
+    public Event event() {
+        return event;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(this.toString());
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (!(obj instanceof EventTask)) {
+            return false;
+        }
+        return Objects.equals(this.event(),
+                              ((WfTriggerEventTask) obj).event());
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("context", context())
+                .add("event", event())
+                .toString();
+    }
+
+    /**
+     * Gets a instance of builder.
+     * @return instance of builder
+     */
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder of WfTriggerEventTask.
+     */
+    public static class Builder extends HandlerTask.Builder {
+
+        /**
+         * Event triggering event task.
+         */
+        private Event event;
+
+
+        /**
+         * Sets event.
+         * @param event event triggering event task
+         * @return Builder of WfTriggerEventTask
+         */
+        public Builder event(Event event) {
+            this.event = event;
+            return this;
+        }
+
+        @Override
+        public Builder context(WorkflowContext context) {
+            super.context(context);
+            return this;
+        }
+
+        /**
+         * Builds WfTriggerEventTask.
+         * @return instance of WfTriggerEventTask
+         * @throws WorkflowException workflow exception
+         */
+        public WfTriggerEventTask build() throws WorkflowException {
+            check(context != null, "context is invalid");
+            check(event != null, "event is invalid");
+            return new WfTriggerEventTask(this);
+        }
+    }
+}
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/Workflow.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/Workflow.java
index 3849afe..01fb92d 100644
--- a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/Workflow.java
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/Workflow.java
@@ -17,6 +17,7 @@
 
 import java.net.URI;
 import java.util.List;
+import java.util.Optional;
 import java.util.Set;
 
 /**
@@ -102,10 +103,25 @@
     List<ProgramCounter> getProgram();
 
     /**
+     * Returns worklet instance with given worklet Name.
+     * @param workletType worklet name
+     * @return Worklet
+     * @throws WorkflowException workflow exception
+     */
+
+    Worklet getTriggerWorkletInstance(String workletType) throws WorkflowException;
+
+    /**
      * Returns worklet description.
      * @param pc program counter
      * @return worklet description list
      */
     WorkletDescription getWorkletDesc(ProgramCounter pc);
 
-}
+    /**
+     * Returns trigger worklet class name if any.
+     * @return trigger worklet class name
+     */
+    Optional<String> getTriggerWorkletClassName();
+
+    }
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowContext.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowContext.java
index 836524d..2398b09 100644
--- a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowContext.java
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowContext.java
@@ -144,6 +144,29 @@
     public abstract long completionEventTimeout();
 
     /**
+     * Sets event map store.
+     * @param contextEventMapStore event map store
+     */
+    public abstract void setEventMapStore(ContextEventMapStore contextEventMapStore);
+
+    /**
+     * Returns the event map store.
+     * @return ContextEventMapStore
+     */
+    public abstract ContextEventMapStore eventMapStore();
+
+
+    /**
+     * Registers an trigger event which has 'eventHint'.
+     * If the event happens, Workflow would be resatrted.
+     * @param event event when trigger happens
+     * @param eventHintSet Set of hint for the event
+     * @throws WorkflowException exception in case any
+     */
+    public abstract void registerTriggerEvent(Class<? extends Event> event,
+                                              Set<String> eventHintSet) throws WorkflowException;
+
+    /**
      * Sets workflow service.
      * @param workflowExecutionService workflow service
      */
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowEventMetaData.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowEventMetaData.java
new file mode 100644
index 0000000..24a485c
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowEventMetaData.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2019-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;
+
+/**
+ * A class representing meta data for workflow event.
+ */
+public class WorkflowEventMetaData {
+
+    private boolean isTriggerSet = false;
+    private ProgramCounter programCounter;
+
+    /**
+     * Constructor of workflow event meta data.
+     * @param isTriggerSet trigger event set for the the workflow
+     * @param programCounter program counter representing worklet type for registered event
+     */
+    public WorkflowEventMetaData(boolean isTriggerSet, ProgramCounter programCounter) {
+        this.isTriggerSet = isTriggerSet;
+        this.programCounter = programCounter;
+    }
+
+    /**
+     * Copy constructor of workflow event meta data.
+     * @param workflowEventMetaData object of WorkflowEventMetaData
+     */
+    public WorkflowEventMetaData(WorkflowEventMetaData workflowEventMetaData) {
+        this.isTriggerSet = workflowEventMetaData.getTriggerFlag();
+        this.programCounter = workflowEventMetaData.getProgramCounter().clone();
+    }
+
+    /**
+     * Returns program counter value related to worflow event.
+     * @return programCounter
+     */
+    public ProgramCounter getProgramCounter() {
+        return programCounter;
+    }
+
+    /**
+     * Returns trigger flag for the workflow.
+     * @return triggerFlag
+     */
+    public boolean getTriggerFlag() {
+        return isTriggerSet;
+    }
+
+
+    /**
+     * Sets true or false for triggerFlag of the workflow.
+     * @param triggerFlag flag to indicate trigger event set for the workflow
+     */
+    public void setTriggerFlag(boolean triggerFlag) {
+        this.isTriggerSet = triggerFlag;
+    }
+
+    /**
+     * Sets program counter representing worklet type for registered event of the workflow.
+     * @param programCounter program counter representing worklet type for registered event
+     */
+    public void setProgramCounterString(ProgramCounter programCounter) {
+        this.programCounter = programCounter;
+    }
+
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("trigger-flag", getTriggerFlag())
+                .add("program-counter", getProgramCounter())
+                .toString();
+    }
+
+}
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowExecutionService.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowExecutionService.java
index c5e00a7..3a41a60 100644
--- a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowExecutionService.java
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowExecutionService.java
@@ -49,9 +49,9 @@
      * @param eventType event type (class name of event)
      * @param eventHintSet Set of event hint value
      * @param contextName workflow context name to be called by this event map
-     * @param programCounterString worklet type to be called by this event map
+     * @param programCounter worklet type to be called by this event map
      * @throws WorkflowException workflow exception
      */
     void registerEventMap(Class<? extends Event> eventType, Set<String> eventHintSet,
-                          String contextName, String programCounterString) throws WorkflowException;
+                          String contextName, ProgramCounter programCounter) throws WorkflowException;
 }
diff --git a/apps/workflow/app/src/main/java/org/onosproject/workflow/impl/DistributedContextEventMapTreeStore.java b/apps/workflow/app/src/main/java/org/onosproject/workflow/impl/DistributedContextEventMapTreeStore.java
index 8cd352e..947eff3 100644
--- a/apps/workflow/app/src/main/java/org/onosproject/workflow/impl/DistributedContextEventMapTreeStore.java
+++ b/apps/workflow/app/src/main/java/org/onosproject/workflow/impl/DistributedContextEventMapTreeStore.java
@@ -21,6 +21,8 @@
 import com.google.common.collect.Maps;
 import org.onosproject.store.service.EventuallyConsistentMap;
 import org.onosproject.store.service.WallClockTimestamp;
+import org.onosproject.workflow.api.ProgramCounter;
+import org.onosproject.workflow.api.WorkflowEventMetaData;
 import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.Deactivate;
@@ -64,10 +66,12 @@
 
     private ApplicationId appId;
 
-    private AsyncDocumentTree<String> eventMapTree;
+    private AsyncDocumentTree<WorkflowEventMetaData> eventMapTree;
 
     private EventuallyConsistentMap<String, Set<String>> hintSetPerCxtMap;
 
+    private static final ProgramCounter INVALID_PC = ProgramCounter.valueOf("INVALID_WORKLET", 0);
+
 
     @Activate
     public void activate() {
@@ -77,9 +81,12 @@
 
         KryoNamespace eventMapNamespace = KryoNamespace.newBuilder()
                 .register(KryoNamespaces.API)
+                .register(ProgramCounter.class)
+                .register(WorkflowEventMetaData.class)
+                .register(Set.class)
                 .build();
 
-        eventMapTree = storageService.<String>documentTreeBuilder()
+        eventMapTree = storageService.<WorkflowEventMetaData>documentTreeBuilder()
                 .withSerializer(Serializer.using(eventMapNamespace))
                 .withName("context-event-map-store")
                 .withOrdering(Ordering.INSERTION)
@@ -103,25 +110,49 @@
 
     @Override
     public void registerEventMap(String eventType, Set<String> eventHintSet,
-                                 String contextName, String programCounterString) throws WorkflowException {
+                                 String contextName, ProgramCounter programCounter) throws WorkflowException {
         for (String eventHint : eventHintSet) {
             //Insert in eventCxtPerHintMap
             DocumentPath dpathForCxt = DocumentPath.from(Lists.newArrayList(
                     "root", eventType, eventHint, contextName));
-            String currentWorkletType = completeVersioned(eventMapTree.get(dpathForCxt));
-            if (currentWorkletType == null) {
-                complete(eventMapTree.createRecursive(dpathForCxt, programCounterString));
+            WorkflowEventMetaData workflowEventMetaData = completeVersioned(eventMapTree.get(dpathForCxt));
+            if (workflowEventMetaData == null) {
+                workflowEventMetaData = new WorkflowEventMetaData(false, programCounter);
+                complete(eventMapTree.createRecursive(dpathForCxt, workflowEventMetaData));
             } else {
-                complete(eventMapTree.replace(dpathForCxt, programCounterString, currentWorkletType));
+                WorkflowEventMetaData updatedWorkflowEventMetaData =
+                        new WorkflowEventMetaData(workflowEventMetaData.getTriggerFlag(), programCounter);
+                complete(eventMapTree.replace(dpathForCxt, updatedWorkflowEventMetaData, workflowEventMetaData));
             }
             log.trace("RegisterEventMap for eventType:{}, eventSet:{}, contextName:{}, pc:{}",
-                     eventType, eventHintSet, contextName, programCounterString);
+                     eventType, eventHintSet, contextName, programCounter.toString());
 
         }
         hintSetPerCxtMap.put(contextName, eventHintSet);
         log.trace("RegisterEventMap in hintSetPerCxt for " +
                          "eventType:{}, eventSet:{}, contextName:{}, pc:{}",
-                 eventType, eventHintSet, contextName, programCounterString);
+                 eventType, eventHintSet, contextName, programCounter.toString());
+    }
+
+    @Override
+    public void registerTriggerFlag(String eventType, Set<String> eventHintSet,
+                                 String contextName) throws WorkflowException {
+        for (String eventHint : eventHintSet) {
+            //Insert in eventCxtPerHintMap
+            DocumentPath dpathForCxt = DocumentPath.from(Lists.newArrayList(
+                    "root", eventType, eventHint, contextName));
+            WorkflowEventMetaData workflowEventMetaData = completeVersioned(eventMapTree.get(dpathForCxt));
+            if (workflowEventMetaData == null) {
+                workflowEventMetaData = new WorkflowEventMetaData(true, INVALID_PC);
+                complete(eventMapTree.createRecursive(dpathForCxt, workflowEventMetaData));
+            } else {
+                WorkflowEventMetaData updatedWorkflowEventMetaData =
+                        new WorkflowEventMetaData(true, workflowEventMetaData.getProgramCounter());
+                complete(eventMapTree.replace(dpathForCxt, updatedWorkflowEventMetaData, workflowEventMetaData));
+            }
+            log.trace("RegisterTriggerFlag for eventType:{}, eventSet:{}, contextName:{}",
+                      eventType, eventHintSet, contextName);
+        }
     }
 
     @Override
@@ -129,28 +160,39 @@
             throws WorkflowException {
 
         Set<String> hints = hintSetPerCxtMap.get(contextName);
+
+        if (Objects.isNull(hints)) {
+            return;
+        }
         for (String eventHint : hints) {
             //Remove from eventCxtPerHintMap
-            complete(eventMapTree.removeNode(DocumentPath.from(Lists.newArrayList(
-                    "root", eventType, eventHint, contextName))));
-            log.trace("UnregisterEventMap from eventCxtPerHintMap for eventType:{}, eventSet:{}, contextName:{}",
-                     eventType, eventHint, contextName);
+            DocumentPath dpathForCxt = DocumentPath.from(Lists.newArrayList(
+                    "root", eventType, eventHint, contextName));
+            WorkflowEventMetaData workflowEventMetaData = completeVersioned(eventMapTree.get(dpathForCxt));
+            if (Objects.nonNull(workflowEventMetaData)) {
+                WorkflowEventMetaData updatedWorkflowEventMetaData = new WorkflowEventMetaData(workflowEventMetaData);
+                updatedWorkflowEventMetaData.setProgramCounterString(INVALID_PC);
+                complete(eventMapTree.replace(dpathForCxt, updatedWorkflowEventMetaData, workflowEventMetaData));
+                log.trace("UnregisterEventMap from eventCxtPerHintMap for eventType:{}, eventSet:{}, contextName:{}",
+                          eventType, eventHint, contextName);
+            }
         }
         hintSetPerCxtMap.remove(contextName);
     }
 
 
     @Override
-    public Map<String, String> getEventMapByHint(String eventType, String eventHint) throws WorkflowException {
+    public Map<String, WorkflowEventMetaData> getEventMapByHint(String eventType,
+                                                                String eventHint) throws WorkflowException {
         DocumentPath path = DocumentPath.from(
                 Lists.newArrayList("root", eventType, eventHint));
-        Map<String, Versioned<String>> contexts = complete(eventMapTree.getChildren(path));
-        Map<String, String> eventMap = Maps.newHashMap();
+        Map<String, Versioned<WorkflowEventMetaData>> contexts = complete(eventMapTree.getChildren(path));
+        Map<String, WorkflowEventMetaData> eventMap = Maps.newHashMap();
         if (Objects.isNull(contexts)) {
             return eventMap;
         }
 
-        for (Map.Entry<String, Versioned<String>> entry : contexts.entrySet()) {
+        for (Map.Entry<String, Versioned<WorkflowEventMetaData>> entry : contexts.entrySet()) {
             eventMap.put(entry.getKey(), entry.getValue().value());
         }
         log.trace("getEventMapByHint returns eventMap {} ", eventMap);
@@ -170,11 +212,25 @@
         }
     }
 
+    @Override
+    public boolean isTriggerSet(String eventType, String eventHint,
+                                String contextName) throws WorkflowException {
+
+        //Remove from eventCxtPerHintMap
+        DocumentPath dpathForCxt = DocumentPath.from(Lists.newArrayList(
+                "root", eventType, eventHint, contextName));
+        WorkflowEventMetaData workflowEventMetaData = completeVersioned(eventMapTree.get(dpathForCxt));
+        if (Objects.nonNull(workflowEventMetaData)) {
+            return workflowEventMetaData.getTriggerFlag();
+        } else {
+            return false;
+        }
+    }
 
     @Override
-    public Map<String, Versioned<String>> getChildren(String path) throws WorkflowException {
+    public Map<String, Versioned<WorkflowEventMetaData>> getChildren(String path) throws WorkflowException {
         DocumentPath dpath = DocumentPath.from(path);
-        Map<String, Versioned<String>> entries = complete(eventMapTree.getChildren(dpath));
+        Map<String, Versioned<WorkflowEventMetaData>> entries = complete(eventMapTree.getChildren(dpath));
         return entries;
     }
 
@@ -188,11 +244,11 @@
     public ObjectNode asJsonTree() throws WorkflowException {
 
         DocumentPath rootPath = DocumentPath.from(Lists.newArrayList("root"));
-        Map<String, Versioned<String>> eventmap = complete(eventMapTree.getChildren(rootPath));
+        Map<String, Versioned<WorkflowEventMetaData>> eventmap = complete(eventMapTree.getChildren(rootPath));
 
         ObjectNode rootNode = JsonNodeFactory.instance.objectNode();
 
-        for (Map.Entry<String, Versioned<String>> eventTypeEntry : eventmap.entrySet()) {
+        for (Map.Entry<String, Versioned<WorkflowEventMetaData>> eventTypeEntry : eventmap.entrySet()) {
 
             String eventType = eventTypeEntry.getKey();
 
@@ -200,9 +256,9 @@
             rootNode.put(eventType, eventTypeNode);
 
             DocumentPath eventTypePath = DocumentPath.from(Lists.newArrayList("root", eventType));
-            Map<String, Versioned<String>> hintmap = complete(eventMapTree.getChildren(eventTypePath));
+            Map<String, Versioned<WorkflowEventMetaData>> hintmap = complete(eventMapTree.getChildren(eventTypePath));
 
-            for (Map.Entry<String, Versioned<String>> hintEntry : hintmap.entrySet()) {
+            for (Map.Entry<String, Versioned<WorkflowEventMetaData>> hintEntry : hintmap.entrySet()) {
 
                 String hint = hintEntry.getKey();
 
@@ -210,10 +266,10 @@
                 eventTypeNode.put(hint, hintNode);
 
                 DocumentPath hintPath = DocumentPath.from(Lists.newArrayList("root", eventType, hint));
-                Map<String, Versioned<String>> contextmap = complete(eventMapTree.getChildren(hintPath));
+                Map<String, Versioned<WorkflowEventMetaData>> contextmap = complete(eventMapTree.getChildren(hintPath));
 
-                for (Map.Entry<String, Versioned<String>> ctxtEntry : contextmap.entrySet()) {
-                    hintNode.put(ctxtEntry.getKey(), ctxtEntry.getValue().value());
+                for (Map.Entry<String, Versioned<WorkflowEventMetaData>> ctxtEntry : contextmap.entrySet()) {
+                    hintNode.put(ctxtEntry.getKey(), ctxtEntry.getValue().value().toString());
                 }
             }
         }
diff --git a/apps/workflow/app/src/main/java/org/onosproject/workflow/impl/WorkFlowEngine.java b/apps/workflow/app/src/main/java/org/onosproject/workflow/impl/WorkFlowEngine.java
index 167e1c4..68c556e 100644
--- a/apps/workflow/app/src/main/java/org/onosproject/workflow/impl/WorkFlowEngine.java
+++ b/apps/workflow/app/src/main/java/org/onosproject/workflow/impl/WorkFlowEngine.java
@@ -32,6 +32,8 @@
 import org.onosproject.workflow.api.EventTimeoutTask;
 import org.onosproject.workflow.api.TimeoutTask;
 import org.onosproject.workflow.api.TimerChain;
+import org.onosproject.workflow.api.TriggerWorklet;
+import org.onosproject.workflow.api.WorkflowEventMetaData;
 import org.onosproject.workflow.api.Worklet;
 import org.onosproject.workflow.api.Workflow;
 import org.onosproject.workflow.api.WorkflowContext;
@@ -220,6 +222,7 @@
         initWorkletExecution(latestContext);
 
         workplaceStore.commitContext(latestContext.name(), latestContext, true);
+
     }
 
     @Override
@@ -229,7 +232,7 @@
             return;
         }
 
-        Map<String, String> eventMap;
+        Map<String, WorkflowEventMetaData> eventMap;
 
         String eventHint;
         try {
@@ -238,6 +241,7 @@
             log.error("Exception: ", e);
             return;
         }
+
         if (eventHint == null) {
             // do nothing
             log.error("Invalid eventHint, event: {}", event);
@@ -246,59 +250,87 @@
 
         try {
             eventMap = eventMapStore.getEventMapByHint(event.getClass().getName(), eventHint);
-        } catch (WorkflowException e) {
-            log.error("Exception: ", e);
-            return;
-        }
-
-        if (Objects.isNull(eventMap) || eventMap.isEmpty()) {
-            // do nothing;
-            log.debug("Invalid eventMap, event: {}", event);
-            return;
-        }
-
-        for (Map.Entry<String, String> entry : eventMap.entrySet()) {
-            String contextName = entry.getKey();
-            String strProgramCounter = entry.getValue();
-            ProgramCounter pc;
-            try {
-                pc = ProgramCounter.valueOf(strProgramCounter);
-            } catch (IllegalArgumentException e) {
-                log.error("Exception: ", e);
+            if (Objects.isNull(eventMap) || eventMap.isEmpty()) {
+                // do nothing;
+                log.debug("Invalid eventMap, event: {}", event);
                 return;
             }
 
-            WorkflowContext context = workplaceStore.getContext(contextName);
-            if (Objects.isNull(context)) {
-                log.info("Invalid context: {}, event: {}", contextName, event);
-                continue;
-            }
-            EventTask eventtask = null;
-            try {
-                eventtask = EventTask.builder()
-                        .event(event)
-                        .eventHint(eventHint)
-                        .context(context)
-                        .programCounter(pc)
-                        .build();
-            } catch (WorkflowException e) {
-                log.error("Exception: ", e);
+            for (Map.Entry<String, WorkflowEventMetaData> entry : eventMap.entrySet()) {
+                String contextName = entry.getKey();
+                ProgramCounter pc = ProgramCounter.valueOf("INVALID_WORKLET", 0);
+                WorkflowContext context = null;
+
+                context = workplaceStore.getContext(contextName);
+
+                if (Objects.isNull(context)) {
+                    log.info("Invalid context: {}, event: {}", contextName, event);
+                    continue;
+                }
+
+                EventTask eventtask = null;
+                if (eventMapStore.isTriggerSet(event.getClass().getName(), eventHint, contextName)) {
+                    try {
+                        eventtask = EventTask.builder()
+                               .event(event)
+                               .eventHint(eventHint)
+                               .context(context)
+                               .programCounter(pc)
+                               .build();
+                    } catch (WorkflowException e) {
+                        log.error("Exception: ", e);
+                    }
+
+                    log.debug("eventtaskAccumulator.add: task: {}", eventtask);
+                    if (!Objects.isNull(eventtask)) {
+                        eventtaskAccumulator.add(eventtask);
+                    }
+                }
+                /*Both type of event is being scheduled here if applicable.
+                If worfklow trigger event is set but may not be a valid one for current event type,
+                then normal worklet event should be processed if applicable. But validity of workflow
+                trigger event would be checked later, so as of now both kind of event would be scheduled.
+                later while trigger event processing, its validity is found to be true, then worklet events
+                would be unregistered and eventually these events wont be processed.*/
+                if (eventMapStore.isEventMapPresent(contextName)) {
+                    try {
+                        pc = entry.getValue().getProgramCounter();
+                    } catch (IllegalArgumentException e) {
+                        log.error("Exception: ", e);
+                        continue;
+                    }
+                    try {
+                        eventtask = EventTask.builder()
+                               .event(event)
+                               .eventHint(eventHint)
+                               .context(context)
+                               .programCounter(pc)
+                               .build();
+                    } catch (WorkflowException e) {
+                        log.error("Exception: ", e);
+                    }
+
+                    log.debug("eventtaskAccumulator.add: task: {}", eventtask);
+                    if (!Objects.isNull(eventtask)) {
+                        eventtaskAccumulator.add(eventtask);
+                    }
+
+                }
             }
 
-            log.debug("eventtaskAccumulator.add: task: {}", eventtask);
-            if (!Objects.isNull(eventtask)) {
-                eventtaskAccumulator.add(eventtask);
-            }
+        } catch (WorkflowException we) {
+            log.error("Exception {} occured in fetching contexts for trigger event {}", we, event);
         }
     }
 
     @Override
     public void registerEventMap(Class<? extends Event> eventType, Set<String> eventHintSet,
-                                 String contextName, String programCounterString) throws WorkflowException {
-        eventMapStore.registerEventMap(eventType.getName(), eventHintSet, contextName, programCounterString);
+                                 String contextName, ProgramCounter programCounter) throws WorkflowException {
+        eventMapStore.registerEventMap(eventType.getName(), eventHintSet, contextName, programCounter);
         for (String eventHint : eventHintSet) {
             for (int i = 0; i < MAX_REGISTER_EVENTMAP_WAITS; i++) {
-                Map<String, String> eventMap = eventMapStore.getEventMapByHint(eventType.getName(), eventHint);
+                Map<String, WorkflowEventMetaData> eventMap =
+                        eventMapStore.getEventMapByHint(eventType.getName(), eventHint);
                 if (eventMap != null && eventMap.containsKey(contextName)) {
                     break;
                 }
@@ -418,6 +450,7 @@
         context.setWorkflowExecutionService(this);
         context.setWorkflowStore(workflowStore);
         context.setWorkplaceStore(workplaceStore);
+        context.setEventMapStore(eventMapStore);
         context.waitCompletion(null, null, null, 0L);
         context.setTriggerNext(false);
     }
@@ -453,14 +486,39 @@
      */
     private EventTask execEventTask(EventTask task) {
 
-        if (!eventMapStore.isEventMapPresent(task.context().name())) {
-            log.trace("EventMap doesnt exist for taskcontext:{}", task.context().name());
+        WorkflowContext context = (WorkflowContext) (task.context());
+        String cxtName = context.name();
+        try {
+            if (eventMapStore.isTriggerSet(task.event().getClass().getName(), task.eventHint(), cxtName)) {
+                WorkflowContext workflowContext = workplaceStore.getContext(cxtName);
+                Workflow workflow = workflowStore.get(workflowContext.workflowId());
+                String triggerWorkletName = workflow.getTriggerWorkletClassName().get();
+                Worklet worklet = workflow.getTriggerWorkletInstance(triggerWorkletName);
+                if (worklet instanceof TriggerWorklet) {
+                    if (((TriggerWorklet) worklet).isTriggerValid(workflowContext, task.event())) {
+                        if (Objects.nonNull(workflowContext.completionEventType())) {
+                            eventMapStore.unregisterEventMap(workflowContext.completionEventType().getName(),
+                                                             workflowContext.name());
+                        }
+                        initWorkletExecution(workflowContext);
+                        workflowContext.setCurrent(ProgramCounter.INIT_PC);
+                        workplaceStore.commitContext(cxtName, workflowContext, true);
+                    }
+                }
+            }
+
+        } catch (WorkflowException we) {
+            log.error("Error Occurred in validating trigger for eventType {} eventHint {} context name {}",
+                      task.eventType(), task.eventHint(), cxtName);
+        }
+
+        if (!eventMapStore.isEventMapPresent(cxtName)) {
+            log.trace("EventMap doesnt exist for taskcontext:{}", cxtName);
             return task;
         }
 
         log.debug("execEventTask- task: {}, hash: {}", task, stringHash(task.context().distributor()));
 
-        WorkflowContext context = (WorkflowContext) (task.context());
         Workflow workflow = workflowStore.get(context.workflowId());
         if (workflow == null) {
             log.error("Invalid workflow {}", context.workflowId());
@@ -803,7 +861,6 @@
             log.info("{} worklet.process(done): {}", latestContext.name(), worklet.tag());
             log.trace("{} context: {}", latestContext.name(), latestContext);
 
-
             if (latestContext.completionEventType() != null) {
                 if (latestContext.completionEventGenerator() == null) {
                     String msg = String.format("Invalid exepecting event(%s), generator(%s)",
@@ -813,8 +870,7 @@
                 }
 
                 registerEventMap(latestContext.completionEventType(), latestContext.completionEventHints(),
-                        latestContext.name(), pc.toString());
-
+                        latestContext.name(), pc);
                 latestContext.completionEventGenerator().apply();
 
                 if (latestContext.completionEventTimeout() != 0L) {
@@ -846,7 +902,6 @@
                     latestContext.setCurrent(workflow.increased(pc));
                 }
             }
-
             workplaceStore.commitContext(latestContext.name(), latestContext, latestContext.triggerNext());
 
         } catch (WorkflowException e) {
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 219436c..7bfe01b 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
@@ -23,8 +23,10 @@
 import org.onosproject.workflow.api.DefaultWorkflowContext;
 import org.onosproject.workflow.api.DefaultWorkplace;
 import org.onosproject.workflow.api.ImmutableListWorkflow;
+import org.onosproject.workflow.api.JsonDataModelInjector;
 import org.onosproject.workflow.api.JsonDataModelTree;
 import org.onosproject.workflow.api.SystemWorkflowContext;
+import org.onosproject.workflow.api.TriggerWorklet;
 import org.onosproject.workflow.api.Workflow;
 import org.onosproject.workflow.api.WorkflowAttribute;
 import org.onosproject.workflow.api.WorkflowContext;
@@ -35,6 +37,7 @@
 import org.onosproject.workflow.api.WorkflowException;
 import org.onosproject.workflow.api.WorkflowExecutionService;
 import org.onosproject.workflow.api.WorkflowStore;
+import org.onosproject.workflow.api.Worklet;
 import org.onosproject.workflow.api.Workplace;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -214,6 +217,17 @@
             WorkflowContext buildingContext = workflow.buildContext(workplace, subTree);
             log.info("registerContext {}", buildingContext.name());
             context.workplaceStore().registerContext(buildingContext.name(), buildingContext);
+
+            if (workflow.getTriggerWorkletClassName().isPresent()) {
+                String triggerWorkletName = workflow.getTriggerWorkletClassName().get();
+                Worklet worklet = workflow.getTriggerWorkletInstance(triggerWorkletName);
+                if (worklet instanceof TriggerWorklet) {
+                    buildingContext.setEventMapStore(context.eventMapStore());
+                    JsonDataModelInjector dataModelInjector = new JsonDataModelInjector();
+                    dataModelInjector.inject(worklet, buildingContext);
+                    ((TriggerWorklet) worklet).register(buildingContext);
+                }
+            }
             submitTrue(context);
 
             context.completed();
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 b397db5..14eb59d 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
@@ -106,6 +106,29 @@
 
             workflowStore.register(workflow);
 
+        // registering new workflow definition
+        uri = URI.create("of-overlay.workflow-nova-with-trigger-to-restart");
+        workflow = ImmutableListWorkflow.builder()
+                .id(uri)
+                //.attribute(WorkflowAttribute.REMOVE_AFTER_COMPLETE)
+                .chain(Ovs.CreateOvsdbDevice.class.getName())
+                .chain(Ovs.UpdateOvsVersion.class.getName())
+                .chain(Ovs.UpdateBridgeId.class.getName())
+                .chain(DefaultWorkletDescription.builder().name(Ovs.CreateBridge.class.getName())
+                       .staticDataModel(BRIDGE_NAME, "br-int")
+                       .build())
+                .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())
+                .trigger(Ovs.TrigerWorkflowAtDeviceReboot.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()
@@ -188,6 +211,7 @@
                                             String hint = event.subject().id().toString();
                                             log.debug("hint: {}", hint);
                                             return hint;
+
                                         }
                                 )
                         );
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..0506793 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
@@ -57,6 +57,7 @@
 import org.onosproject.ovsdb.controller.OvsdbNodeId;
 import org.onosproject.workflow.api.AbstractWorklet;
 import org.onosproject.workflow.api.JsonDataModel;
+import org.onosproject.workflow.api.TriggerWorklet;
 import org.onosproject.workflow.api.WorkflowContext;
 import org.onosproject.workflow.api.WorkflowException;
 import org.onosproject.workflow.api.StaticDataModel;
@@ -67,6 +68,7 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 import java.util.Objects;
@@ -1312,5 +1314,40 @@
             }
         }
     }
+
+    /**
+     * Work-let class for trigger event registration and validation.
+     */
+    public static class TrigerWorkflowAtDeviceReboot extends TriggerWorklet {
+
+        @JsonDataModel(path = MODEL_MGMT_IP)
+        String strMgmtIp;
+
+        String strOfDevIdUnderlay;
+
+        @Override
+        public void register(WorkflowContext context) throws WorkflowException {
+            DeviceId brphyDevId = OvsUtil.buildOfDeviceId(IpAddress.valueOf(strMgmtIp), DEVID_IDX_BRIDGE_UNDERLAY_NOVA);
+            Set<String> eventHintSet = new HashSet<>();
+            eventHintSet.add(brphyDevId.toString());
+            context.registerTriggerEvent(DeviceEvent.class, eventHintSet);
+        }
+
+        @Override
+        public boolean isTriggerValid(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_AVAILABILITY_CHANGED:
+                    return !context.getService(DeviceService.class).isAvailable(device.id());
+                default:
+                    return false;
+            }
+        }
+    }
 }
 
diff --git a/apps/workflow/ofoverlay/test-cfg/network-cfg-cr-trigger-event-wf.json b/apps/workflow/ofoverlay/test-cfg/network-cfg-cr-trigger-event-wf.json
new file mode 100755
index 0000000..f837445
--- /dev/null
+++ b/apps/workflow/ofoverlay/test-cfg/network-cfg-cr-trigger-event-wf.json
@@ -0,0 +1,41 @@
+{
+    "apps": {
+        "org.onosproject.workflow": {
+          "workflow" : {
+            "rpc" : [
+              {
+                "op"   : "workflow.invoke",
+                "params" : {
+                  "workplace" : "Nova-000",
+                  "id"        : "of-overlay.workflow-nova-with-trigger-to-restart",
+                  "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" : [ "nova0_1" ],
+                    "vtepIp" : "120.0.0.200/24",
+
+                    "annotations" : {
+                      "rackId" : 1,
+                      "rackPosition" : 3
+                    }
+
+                  }
+                },
+                "id" : "00001@10.0.0.1"
+              }
+            ]
+          }
+        }
+    }
+}