Add CheckServiceProcessStatus workflow 83/102383/1
authorhetengjiao <hetengjiao@chinamobile.com>
Wed, 26 Feb 2020 09:22:45 +0000 (17:22 +0800)
committerhetengjiao <hetengjiao@chinamobile.com>
Wed, 26 Feb 2020 09:22:54 +0000 (17:22 +0800)
Issue-ID: SO-2368

Change-Id: I33b7b21907f98f4934dc410e9bd3a252210bc58e
Signed-off-by: hetengjiao <hetengjiao@chinamobile.com>
bpmn/so-bpmn-infrastructure-common/src/main/groovy/org/onap/so/bpmn/infrastructure/scripts/CheckServiceProcessStatus.groovy [new file with mode: 0644]
bpmn/so-bpmn-infrastructure-flows/src/main/resources/subprocess/CheckServiceProcessStatus.bpmn [new file with mode: 0644]

diff --git a/bpmn/so-bpmn-infrastructure-common/src/main/groovy/org/onap/so/bpmn/infrastructure/scripts/CheckServiceProcessStatus.groovy b/bpmn/so-bpmn-infrastructure-common/src/main/groovy/org/onap/so/bpmn/infrastructure/scripts/CheckServiceProcessStatus.groovy
new file mode 100644 (file)
index 0000000..3233bff
--- /dev/null
@@ -0,0 +1,333 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ # Copyright (c) 2019, CMCC Technologies Co., Ltd.
+ #
+ # 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.so.bpmn.infrastructure.scripts
+
+import org.camunda.bpm.engine.delegate.BpmnError
+import org.camunda.bpm.engine.delegate.DelegateExecution
+import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor
+import org.onap.so.bpmn.common.scripts.ExceptionUtil
+import org.onap.so.bpmn.common.scripts.RequestDBUtil
+import org.onap.so.bpmn.core.json.JsonUtils
+import org.onap.so.client.aai.AAIResourcesClient
+import org.onap.so.db.request.beans.OperationStatus
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
+
+import java.util.concurrent.TimeUnit
+
+import static org.apache.commons.lang3.StringUtils.isBlank
+
+class CheckServiceProcessStatus extends AbstractServiceTaskProcessor  {
+
+
+    String Prefix="CSPS_"
+
+    ExceptionUtil exceptionUtil = new ExceptionUtil()
+
+    RequestDBUtil requestDBUtil = new RequestDBUtil()
+
+    JsonUtils jsonUtil = new JsonUtils()
+
+    AAIResourcesClient client = getAAIClient()
+
+    private static final Logger logger = LoggerFactory.getLogger(CheckServiceProcessStatus.class)
+
+    @Override
+    void preProcessRequest(DelegateExecution execution) {
+        logger.debug(Prefix + "CheckServiceProcessStatus preProcessRequest Start")
+        execution.setVariable("prefix", Prefix)
+
+        String serviceInstanceId = execution.getVariable("serviceInstanceId")
+        String operationId = execution.getVariable("operationId")
+        String parentServiceInstanceId = execution.getVariable("parentServiceInstanceId")
+        String parentOperationId = execution.getVariable("parentOperationId")
+
+        if (isBlank(serviceInstanceId) || isBlank(operationId)) {
+            String msg = "Exception in" + Prefix + "preProcessRequest: Input serviceInstanceId or operationId is null"
+            exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
+        }
+
+        if (isBlank(parentServiceInstanceId) || isBlank(parentOperationId)) {
+            execution.setVariable("isNeedUpdateParentStatus", false)
+        }
+
+        String globalSubscriberId = execution.getVariable("globalSubscriberId")
+        if (isBlank(globalSubscriberId)) {
+            execution.setVariable("globalSubscriberId", "5GCustomer")
+        }
+
+        // serviceType: type of service
+        String serviceType = execution.getVariable("processServiceType")
+        if (isBlank(serviceType)) {
+            execution.setVariable("processServiceType", "service")
+        }
+
+        // operationType: type of service
+        String operationType = execution.getVariable("operationType")
+        if (isBlank(operationType)) {
+            execution.setVariable("operationType", "CREATE")
+        }
+
+        //successConditions: processing end success conditions
+        List<String> successConditions = execution.getVariable("successConditions") as List
+
+        //errorConditions: processing end error conditions
+        List<String> errorConditions = execution.getVariable("errorConditions") as List
+
+        if ((successConditions == null || successConditions.size() < 1)
+                && (errorConditions == null || errorConditions.size() < 1)) {
+            String msg = "Exception in" + Prefix + "preProcessRequest: conditions is null"
+            exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
+        } else {
+            for (int i = 0; i < successConditions.size(); i++) {
+                String condition = successConditions.get(i)
+                successConditions.set(i, condition.toLowerCase())
+            }
+            for (int i = 0; i < errorConditions.size(); i++) {
+                String condition = errorConditions.get(i)
+                errorConditions.set(i, condition.toLowerCase())
+            }
+        }
+
+        execution.setVariable("startTime", System.currentTimeMillis())
+
+        String initProgress = execution.getVariable("initProgress")
+
+        if (isBlank(initProgress)) {
+            execution.setVariable("initProgress", 0)
+        }
+
+        String endProgress = execution.getVariable("endProgress")
+
+        if (isBlank(endProgress)) {
+            execution.setVariable("endProgress", 100)
+        }
+
+        execution.setVariable("progress", 0)
+        logger.debug(Prefix + "preProcessRequest Exit")
+    }
+
+
+    /**
+     * check service status through request operation id, update operation status
+    */
+    def preCheckServiceStatusReq = { DelegateExecution execution ->
+        logger.trace(Prefix + "preCheckServiceStatusReq Start")
+        String serviceInstanceId = execution.getVariable("serviceInstanceId") as String
+        String operationId = execution.getVariable("operationId") as String
+        requestDBUtil.getOperationStatus(execution, serviceInstanceId, operationId)
+        logger.trace(Prefix + "preCheckServiceStatusReq Exit")
+    }
+
+
+    /**
+     * handle service status, if service status is finished or error, set the service status
+     * @param execution
+     */
+    def handlerServiceStatusResp = { DelegateExecution execution ->
+        logger.trace(Prefix + "handlerServiceStatusResp Start")
+        String msg
+        try {
+            def dbResponseCode = execution.getVariable("dbResponseCode") as Integer
+            if (dbResponseCode >= 200 && dbResponseCode < 400) {
+                String dbResponse = execution.getVariable("dbResponse")
+                def dbResponseJson = jsonUtil.xml2json(dbResponse) as String
+
+                String result = jsonUtil.getJsonValue(dbResponseJson,
+                        "Envelope.Body.getServiceOperationStatusResponse.return.result")
+
+                if (isSuccessCompleted(execution, result)) {
+
+                    handlerSuccess(execution, result)
+                    execution.setVariable("isAllFinished", "true")
+
+                    logger.debug(Prefix + "handlerServiceStatusResp: service success finished, dbResponse_result: "
+                            + result)
+
+                } else if (isErrorCompleted(execution, result)) {
+
+                    handlerError(execution, result)
+                    execution.setVariable("isAllFinished", "true")
+
+                    logger.debug(Prefix + "handlerServiceStatusResp: service error finished, dbResponse_result: "
+                            + result)
+
+                } else {
+                    String progress = jsonUtil.getJsonValue(dbResponseJson,
+                            "Envelope.Body.getServiceOperationStatusResponse.return.progress")
+
+                    String oldProgress = execution.getVariable("progress")
+
+                    if (progress == oldProgress) {
+                        execution.setVariable("isNeedUpdateDB", false)
+                    } else {
+                        execution.setVariable("progress", progress)
+                        execution.setVariable("isNeedUpdateDB", true)
+                    }
+                    execution.setVariable("isAllFinished", "false")
+                    TimeUnit.SECONDS.sleep(10)
+                }
+            } else {
+                execution.setVariable("isAllFinished", "false")
+                //todo: retry
+                TimeUnit.MILLISECONDS.sleep(10)
+            }
+
+        } catch (BpmnError e) {
+            throw e
+        } catch (Exception ex) {
+            msg = "Exception in " + Prefix + "handlerServiceStatusResp: " + ex.getMessage()
+            logger.debug(msg)
+            exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
+        }
+
+        logger.trace(Prefix + "handlerServiceStatusResp Exit")
+    }
+
+
+    def timeWaitDelay = { DelegateExecution execution ->
+
+        Long startTime = execution.getVariable("startTime") as Long
+        Long timeOut = execution.getVariable("timeOut") as Long
+
+        timeOut = timeOut == null ? 3 * 60 * 60 * 1000 : timeOut
+
+        if (System.currentTimeMillis() - startTime > timeOut) {
+
+            handlerTimeOut(execution)
+            execution.setVariable("isTimeOut", "YES")
+
+        } else {
+            execution.setVariable("isTimeOut", "NO")
+        }
+    }
+
+
+    private handlerTimeOut = { DelegateExecution execution ->
+
+        Map<String, Object> paramMap = execution.getVariable("timeOutParamMap") as Map
+
+        handlerProcess(execution, "error", paramMap, "error", "with timeout")
+    }
+
+
+    private handlerSuccess = { DelegateExecution execution, String result ->
+
+        Map<String, Object> paramMap = execution.getVariable("successParamMap") as Map
+
+        handlerProcess(execution, result, paramMap, "deactivated", "success")
+    }
+
+
+    private handlerError = { DelegateExecution execution, String result ->
+
+        Map<String, Object> paramMap = execution.getVariable("errorParamMap") as Map
+
+        handlerProcess(execution, result, paramMap, "error", "with error")
+    }
+
+
+    private handlerProcess = { DelegateExecution execution, String result, def paramMap, def status, def msg ->
+
+        if (paramMap != null) {
+            for (Map.Entry<String, Object> entry : paramMap.entrySet()) {
+                execution.setVariable(entry.getKey(), entry.getValue())
+            }
+        }
+
+
+        if (isBlank(execution.getVariable("operationStatus") as String)) {
+            execution.setVariable("operationStatus", result)
+        }
+
+
+        if (isBlank(execution.getVariable("operationContent") as String)) {
+            String operationContent =  execution.getVariable("processServiceType") + " " +
+                    execution.getVariable("operationType") + " operation finished " + msg
+            execution.setVariable("operationContent", operationContent)
+        }
+
+        if (isBlank(execution.getVariable("orchestrationStatus") as String)) {
+            execution.setVariable("orchestrationStatus", status)
+        }
+
+    }
+
+
+    /**
+     * judge if the service processing success finished
+     */
+    private isSuccessCompleted = { DelegateExecution execution, String result ->
+
+        //successConditions: processing end success conditions
+        List<String> successConditions = execution.getVariable("successConditions") as List
+
+        result = result.toLowerCase()
+        if (successConditions.contains(result)) {
+            return true
+        }
+        return false
+    }
+
+
+    /**
+     * judge if the service processing error finished
+     */
+    private isErrorCompleted = { DelegateExecution execution, String result ->
+
+        //errorConditions: processing end error conditions
+        List<String> errorConditions = execution.getVariable("errorConditions") as List
+
+        result = result.toLowerCase()
+        if (errorConditions.contains(result)) {
+            return true
+        }
+        return false
+    }
+
+
+    def preUpdateOperationProgress = { DelegateExecution execution ->
+        logger.trace(Prefix + "prepareUpdateOperationStatus Start")
+
+        def progress = execution.getVariable("progress") as Integer
+        def initProgress = execution.getVariable("initProgress") as Integer
+        def endProgress = execution.getVariable("endProgress") as Integer
+
+        def resProgress = (initProgress + (endProgress - initProgress) / 100 * progress) as Integer
+
+        def operationType = execution.getVariable("operationType")
+        def operationContent =  execution.getVariable("processServiceType") + " " +
+                operationType + " operation processing " + resProgress
+
+        // update status creating
+        OperationStatus status = new OperationStatus()
+        status.setServiceId(execution.getVariable("parentServiceInstanceId") as String)
+        status.setOperationId(execution.getVariable("parentOperationId") as String)
+        status.setOperation(operationType as String)
+        status.setResult("processing")
+        status.setProgress(resProgress as String)
+        status.setOperationContent(operationContent as String)
+        status.setUserId(execution.getVariable("globalSubscriberId") as String)
+
+        requestDBUtil.prepareUpdateOperationStatus(execution, status)
+        logger.trace(Prefix + "prepareUpdateOperationStatus Exit")
+    }
+}
diff --git a/bpmn/so-bpmn-infrastructure-flows/src/main/resources/subprocess/CheckServiceProcessStatus.bpmn b/bpmn/so-bpmn-infrastructure-flows/src/main/resources/subprocess/CheckServiceProcessStatus.bpmn
new file mode 100644 (file)
index 0000000..279dd2a
--- /dev/null
@@ -0,0 +1,225 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_0lf96js" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.4.1">
+  <bpmn:process id="CheckServiceProcessStatus" name="CheckServiceProcessStatus" isExecutable="true">
+    <bpmn:startEvent id="StartEvent_1" name="start check processing status">
+      <bpmn:outgoing>SequenceFlow_1g4lx01</bpmn:outgoing>
+    </bpmn:startEvent>
+    <bpmn:scriptTask id="ScriptTask_1mlave2" name="Prepare service Check Process status Req&#10;" scriptFormat="groovy">
+      <bpmn:incoming>SequenceFlow_0e29y0f</bpmn:incoming>
+      <bpmn:incoming>SequenceFlow_1n5nl53</bpmn:incoming>
+      <bpmn:outgoing>SequenceFlow_0r1x26k</bpmn:outgoing>
+      <bpmn:script>import org.onap.so.bpmn.infrastructure.scripts.*
+def csi= new CheckServiceProcessStatus()
+csi.preCheckServiceStatusReq(execution)</bpmn:script>
+    </bpmn:scriptTask>
+    <bpmn:serviceTask id="ServiceTask_0w5fmqn" name="get service Operation Status&#10;">
+      <bpmn:extensionElements>
+        <camunda:connector>
+          <camunda:inputOutput>
+            <camunda:inputParameter name="url">${dbAdapterEndpoint}</camunda:inputParameter>
+            <camunda:inputParameter name="headers">
+              <camunda:map>
+                <camunda:entry key="content-type">application/soap+xml</camunda:entry>
+                <camunda:entry key="Authorization">Basic YnBlbDpwYXNzd29yZDEk</camunda:entry>
+              </camunda:map>
+            </camunda:inputParameter>
+            <camunda:inputParameter name="payload">${getOperationStatus}</camunda:inputParameter>
+            <camunda:inputParameter name="method">POST</camunda:inputParameter>
+            <camunda:outputParameter name="dbResponseCode">${statusCode}</camunda:outputParameter>
+            <camunda:outputParameter name="dbResponse">${response}</camunda:outputParameter>
+          </camunda:inputOutput>
+          <camunda:connectorId>http-connector</camunda:connectorId>
+        </camunda:connector>
+      </bpmn:extensionElements>
+      <bpmn:incoming>SequenceFlow_0r1x26k</bpmn:incoming>
+      <bpmn:outgoing>SequenceFlow_009p8v1</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:scriptTask id="ScriptTask_0z37e29" name="handler service status Response&#10;" scriptFormat="groovy">
+      <bpmn:incoming>SequenceFlow_009p8v1</bpmn:incoming>
+      <bpmn:outgoing>SequenceFlow_0yws8fh</bpmn:outgoing>
+      <bpmn:script>import org.onap.so.bpmn.infrastructure.scripts.*
+def csi= new CheckServiceProcessStatus()
+csi.handlerServiceStatusResp(execution)</bpmn:script>
+    </bpmn:scriptTask>
+    <bpmn:exclusiveGateway id="ExclusiveGateway_0gk7p3l" name="Is service process finished?&#10;" default="SequenceFlow_01o92x6">
+      <bpmn:incoming>SequenceFlow_0yws8fh</bpmn:incoming>
+      <bpmn:outgoing>SequenceFlow_18jgpa8</bpmn:outgoing>
+      <bpmn:outgoing>SequenceFlow_01o92x6</bpmn:outgoing>
+    </bpmn:exclusiveGateway>
+    <bpmn:scriptTask id="ScriptTask_1ao91w3" name="Time Delay" scriptFormat="groovy">
+      <bpmn:incoming>SequenceFlow_1pxnqsp</bpmn:incoming>
+      <bpmn:incoming>SequenceFlow_1ktr440</bpmn:incoming>
+      <bpmn:outgoing>SequenceFlow_0e29y0f</bpmn:outgoing>
+      <bpmn:script>import org.onap.so.bpmn.infrastructure.scripts.*
+def csi= new CheckServiceProcessStatus()
+csi.timeWaitDelay(execution)</bpmn:script>
+    </bpmn:scriptTask>
+    <bpmn:sequenceFlow id="SequenceFlow_0e29y0f" sourceRef="ScriptTask_1ao91w3" targetRef="ScriptTask_1mlave2" />
+    <bpmn:sequenceFlow id="SequenceFlow_0r1x26k" sourceRef="ScriptTask_1mlave2" targetRef="ServiceTask_0w5fmqn" />
+    <bpmn:sequenceFlow id="SequenceFlow_009p8v1" sourceRef="ServiceTask_0w5fmqn" targetRef="ScriptTask_0z37e29" />
+    <bpmn:sequenceFlow id="SequenceFlow_0yws8fh" sourceRef="ScriptTask_0z37e29" targetRef="ExclusiveGateway_0gk7p3l" />
+    <bpmn:sequenceFlow id="SequenceFlow_18jgpa8" name="yes" sourceRef="ExclusiveGateway_0gk7p3l" targetRef="EndEvent_0a3w3xw">
+      <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">#{(execution.getVariable("isAllFinished") == "true") || (execution.getVariable("isTimeOut") == "YES")}</bpmn:conditionExpression>
+    </bpmn:sequenceFlow>
+    <bpmn:endEvent id="EndEvent_0a3w3xw">
+      <bpmn:incoming>SequenceFlow_18jgpa8</bpmn:incoming>
+    </bpmn:endEvent>
+    <bpmn:sequenceFlow id="SequenceFlow_1g4lx01" sourceRef="StartEvent_1" targetRef="Task_1djj44q" />
+    <bpmn:sequenceFlow id="SequenceFlow_1n5nl53" sourceRef="Task_1djj44q" targetRef="ScriptTask_1mlave2" />
+    <bpmn:scriptTask id="Task_1djj44q" name="Prepare request" scriptFormat="groovy">
+      <bpmn:incoming>SequenceFlow_1g4lx01</bpmn:incoming>
+      <bpmn:outgoing>SequenceFlow_1n5nl53</bpmn:outgoing>
+      <bpmn:script>import org.onap.so.bpmn.infrastructure.scripts.*
+def csi= new CheckServiceProcessStatus()
+csi.preProcessRequest(execution)</bpmn:script>
+    </bpmn:scriptTask>
+    <bpmn:scriptTask id="ScriptTask_0oic8cv" name="prepare Update Service Operation progress" scriptFormat="groovy">
+      <bpmn:incoming>SequenceFlow_0591ght</bpmn:incoming>
+      <bpmn:outgoing>SequenceFlow_1q8dls4</bpmn:outgoing>
+      <bpmn:script>import org.onap.so.bpmn.infrastructure.scripts.*
+def csi= new CheckServiceProcessStatus()
+csi.preUpdateOperationProgress(execution)</bpmn:script>
+    </bpmn:scriptTask>
+    <bpmn:sequenceFlow id="SequenceFlow_1q8dls4" sourceRef="ScriptTask_0oic8cv" targetRef="ServiceTask_1b60rre" />
+    <bpmn:serviceTask id="ServiceTask_1b60rre" name="Update Service Operation Status">
+      <bpmn:extensionElements>
+        <camunda:connector>
+          <camunda:inputOutput>
+            <camunda:inputParameter name="url">${dbAdapterEndpoint}</camunda:inputParameter>
+            <camunda:inputParameter name="headers">
+              <camunda:map>
+                <camunda:entry key="content-type">application/soap+xml</camunda:entry>
+                <camunda:entry key="Authorization">Basic YnBlbDpwYXNzd29yZDEk</camunda:entry>
+              </camunda:map>
+            </camunda:inputParameter>
+            <camunda:inputParameter name="payload">${updateOperationStatus}</camunda:inputParameter>
+            <camunda:inputParameter name="method">POST</camunda:inputParameter>
+            <camunda:outputParameter name="CSMF_dbResponseCode">${statusCode}</camunda:outputParameter>
+            <camunda:outputParameter name="CSMF_dbResponse">${response}</camunda:outputParameter>
+          </camunda:inputOutput>
+          <camunda:connectorId>http-connector</camunda:connectorId>
+        </camunda:connector>
+      </bpmn:extensionElements>
+      <bpmn:incoming>SequenceFlow_1q8dls4</bpmn:incoming>
+      <bpmn:outgoing>SequenceFlow_1pxnqsp</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:sequenceFlow id="SequenceFlow_1pxnqsp" sourceRef="ServiceTask_1b60rre" targetRef="ScriptTask_1ao91w3" />
+    <bpmn:sequenceFlow id="SequenceFlow_01o92x6" sourceRef="ExclusiveGateway_0gk7p3l" targetRef="ExclusiveGateway_1pdfjh4" />
+    <bpmn:exclusiveGateway id="ExclusiveGateway_1pdfjh4" name="isNeedUpdateDB?&#10;" default="SequenceFlow_1ktr440">
+      <bpmn:incoming>SequenceFlow_01o92x6</bpmn:incoming>
+      <bpmn:outgoing>SequenceFlow_0591ght</bpmn:outgoing>
+      <bpmn:outgoing>SequenceFlow_1ktr440</bpmn:outgoing>
+    </bpmn:exclusiveGateway>
+    <bpmn:sequenceFlow id="SequenceFlow_0591ght" name="yes" sourceRef="ExclusiveGateway_1pdfjh4" targetRef="ScriptTask_0oic8cv">
+      <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">#{(execution.getVariable("isNeedUpdateDB" )  == true)}</bpmn:conditionExpression>
+    </bpmn:sequenceFlow>
+    <bpmn:sequenceFlow id="SequenceFlow_1ktr440" name="no" sourceRef="ExclusiveGateway_1pdfjh4" targetRef="ScriptTask_1ao91w3" />
+  </bpmn:process>
+  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
+    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="CheckServiceProcessStatus">
+      <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
+        <dc:Bounds x="179" y="159" width="36" height="36" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="156" y="202" width="87" height="27" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="ScriptTask_1mlave2_di" bpmnElement="ScriptTask_1mlave2">
+        <dc:Bounds x="460" y="137" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="ServiceTask_0w5fmqn_di" bpmnElement="ServiceTask_0w5fmqn">
+        <dc:Bounds x="610" y="137" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="ScriptTask_0z37e29_di" bpmnElement="ScriptTask_0z37e29">
+        <dc:Bounds x="770" y="137" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="ExclusiveGateway_0gk7p3l_di" bpmnElement="ExclusiveGateway_0gk7p3l" isMarkerVisible="true">
+        <dc:Bounds x="955" y="152" width="50" height="50" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="944" y="122" width="89" height="40" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="ScriptTask_1ao91w3_di" bpmnElement="ScriptTask_1ao91w3">
+        <dc:Bounds x="460" y="290" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge id="SequenceFlow_0e29y0f_di" bpmnElement="SequenceFlow_0e29y0f">
+        <di:waypoint x="510" y="290" />
+        <di:waypoint x="510" y="217" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_0r1x26k_di" bpmnElement="SequenceFlow_0r1x26k">
+        <di:waypoint x="560" y="177" />
+        <di:waypoint x="610" y="177" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_009p8v1_di" bpmnElement="SequenceFlow_009p8v1">
+        <di:waypoint x="710" y="177" />
+        <di:waypoint x="770" y="177" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_0yws8fh_di" bpmnElement="SequenceFlow_0yws8fh">
+        <di:waypoint x="870" y="177" />
+        <di:waypoint x="955" y="177" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_18jgpa8_di" bpmnElement="SequenceFlow_18jgpa8">
+        <di:waypoint x="1005" y="177" />
+        <di:waypoint x="1132" y="177" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="1024" y="159" width="17" height="14" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="EndEvent_0a3w3xw_di" bpmnElement="EndEvent_0a3w3xw">
+        <dc:Bounds x="1132" y="159" width="36" height="36" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge id="SequenceFlow_1g4lx01_di" bpmnElement="SequenceFlow_1g4lx01">
+        <di:waypoint x="215" y="177" />
+        <di:waypoint x="270" y="177" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_1n5nl53_di" bpmnElement="SequenceFlow_1n5nl53">
+        <di:waypoint x="370" y="177" />
+        <di:waypoint x="460" y="177" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="ScriptTask_1di7x3h_di" bpmnElement="Task_1djj44q">
+        <dc:Bounds x="270" y="137" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="ScriptTask_0oic8cv_di" bpmnElement="ScriptTask_0oic8cv">
+        <dc:Bounds x="930" y="430" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge id="SequenceFlow_1q8dls4_di" bpmnElement="SequenceFlow_1q8dls4">
+        <di:waypoint x="930" y="470" />
+        <di:waypoint x="780" y="470" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="ServiceTask_1b60rre_di" bpmnElement="ServiceTask_1b60rre">
+        <dc:Bounds x="680" y="430" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge id="SequenceFlow_1pxnqsp_di" bpmnElement="SequenceFlow_1pxnqsp">
+        <di:waypoint x="680" y="470" />
+        <di:waypoint x="510" y="470" />
+        <di:waypoint x="510" y="370" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_01o92x6_di" bpmnElement="SequenceFlow_01o92x6">
+        <di:waypoint x="980" y="202" />
+        <di:waypoint x="980" y="305" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="964" y="243" width="13" height="14" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="ExclusiveGateway_1pdfjh4_di" bpmnElement="ExclusiveGateway_1pdfjh4" isMarkerVisible="true">
+        <dc:Bounds x="955" y="305" width="50" height="50" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="1007" y="310" width="86" height="40" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge id="SequenceFlow_0591ght_di" bpmnElement="SequenceFlow_0591ght">
+        <di:waypoint x="980" y="355" />
+        <di:waypoint x="980" y="430" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="987" y="390" width="17" height="14" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_1ktr440_di" bpmnElement="SequenceFlow_1ktr440">
+        <di:waypoint x="955" y="330" />
+        <di:waypoint x="560" y="330" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="751" y="312" width="13" height="14" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+    </bpmndi:BPMNPlane>
+  </bpmndi:BPMNDiagram>
+</bpmn:definitions>