2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * Copyright (C) 2017 Huawei Technologies Co., Ltd. All rights reserved.
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
21 package org.openecomp.mso.bpmn.infrastructure.scripts
23 import org.json.JSONArray;
25 import static org.apache.commons.lang3.StringUtils.*;
26 import groovy.xml.XmlUtil
29 import org.openecomp.mso.bpmn.core.json.JsonUtils
30 import org.openecomp.mso.bpmn.common.scripts.AbstractServiceTaskProcessor
31 import org.openecomp.mso.bpmn.common.scripts.ExceptionUtil
32 import org.openecomp.mso.bpmn.common.scripts.SDNCAdapterUtils
33 import org.openecomp.mso.bpmn.core.WorkflowException
34 import org.openecomp.mso.rest.APIResponse;
35 import org.openecomp.mso.rest.RESTClient
36 import org.openecomp.mso.rest.RESTConfig
38 import java.util.UUID;
39 import javax.xml.parsers.DocumentBuilder
40 import javax.xml.parsers.DocumentBuilderFactory
42 import org.camunda.bpm.engine.delegate.BpmnError
43 import org.camunda.bpm.engine.runtime.Execution
44 import org.json.JSONObject;
45 import org.apache.commons.lang3.*
46 import org.apache.commons.codec.binary.Base64;
47 import org.springframework.web.util.UriUtils;
48 import org.w3c.dom.Document
49 import org.w3c.dom.Element
50 import org.w3c.dom.Node
51 import org.w3c.dom.NodeList
52 import org.xml.sax.InputSource
54 import com.fasterxml.jackson.jaxrs.json.annotation.JSONP.Def;
57 * This groovy class supports the <class>DoDeleteE2EServiceInstance.bpmn</class> process.
60 * @param - msoRequestId
61 * @param - globalSubscriberId - O
62 * @param - subscriptionServiceType - O
63 * @param - serviceInstanceId
64 * @param - serviceInstanceName - O
65 * @param - serviceInputParams (should contain aic_zone for serviceTypes TRANSPORT,ATM)
66 * @param - sdncVersion
67 * @param - failNotFound - TODO
68 * @param - serviceInputParams - TODO
71 * @param - WorkflowException
75 public class DoCustomDeleteE2EServiceInstance extends AbstractServiceTaskProcessor {
77 String Prefix="DDELSI_"
78 ExceptionUtil exceptionUtil = new ExceptionUtil()
79 JsonUtils jsonUtil = new JsonUtils()
81 public void preProcessRequest (Execution execution) {
82 def isDebugEnabled = execution.getVariable("isDebugLogEnabled")
83 utils.log("INFO"," ***** preProcessRequest *****", isDebugEnabled)
87 String requestId = execution.getVariable("msoRequestId")
88 execution.setVariable("prefix",Prefix)
91 //requestDetails.subscriberInfo. for AAI GET & PUT & SDNC assignToplology
92 String globalSubscriberId = execution.getVariable("globalSubscriberId") //globalCustomerId
93 if (globalSubscriberId == null)
95 execution.setVariable("globalSubscriberId", "")
98 //requestDetails.requestParameters. for AAI PUT & SDNC assignTopology
99 String serviceType = execution.getVariable("serviceType")
100 if (serviceType == null)
102 execution.setVariable("serviceType", "")
105 //Generated in parent for AAI PUT
106 String serviceInstanceId = execution.getVariable("serviceInstanceId")
107 if (isBlank(serviceInstanceId)){
108 msg = "Input serviceInstanceId is null"
109 utils.log("INFO", msg, isDebugEnabled)
110 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
113 String sdncCallbackUrl = execution.getVariable('URN_mso_workflow_sdncadapter_callback')
114 if (isBlank(sdncCallbackUrl)) {
115 msg = "URN_mso_workflow_sdncadapter_callback is null"
116 utils.log("INFO", msg, isDebugEnabled)
117 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
119 execution.setVariable("sdncCallbackUrl", sdncCallbackUrl)
120 utils.log("INFO","SDNC Callback URL: " + sdncCallbackUrl, isDebugEnabled)
122 StringBuilder sbParams = new StringBuilder()
123 Map<String, String> paramsMap = execution.getVariable("serviceInputParams")
124 if (paramsMap != null)
126 sbParams.append("<service-input-parameters>")
127 for (Map.Entry<String, String> entry : paramsMap.entrySet()) {
129 String paramName = entry.getKey()
130 String paramValue = entry.getValue()
133 <name>${paramName}</name>
134 <value>${paramValue}</value>
137 sbParams.append(paramsXml)
139 sbParams.append("</service-input-parameters>")
141 String siParamsXml = sbParams.toString()
142 if (siParamsXml == null)
144 execution.setVariable("siParamsXml", siParamsXml)
146 } catch (BpmnError e) {
148 } catch (Exception ex){
149 msg = "Exception in preProcessRequest " + ex.getMessage()
150 utils.log("INFO", msg, isDebugEnabled)
151 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
153 utils.log("INFO"," ***** Exit preProcessRequest *****", isDebugEnabled)
157 public void preProcessVFCDelete (Execution execution) {
160 public void postProcessVFCDelete(Execution execution, String response, String method) {
163 public void preProcessSDNCDelete (Execution execution) {
164 def isDebugEnabled = execution.getVariable("isDebugLogEnabled")
165 utils.log("INFO"," ***** preProcessSDNCDelete *****", isDebugEnabled)
169 def serviceInstanceId = execution.getVariable("serviceInstanceId")
170 def serviceInstanceName = execution.getVariable("serviceInstanceName")
171 def callbackURL = execution.getVariable("sdncCallbackUrl")
172 def requestId = execution.getVariable("msoRequestId")
173 def serviceId = execution.getVariable("productFamilyId")
174 def subscriptionServiceType = execution.getVariable("subscriptionServiceType")
175 def globalSubscriberId = execution.getVariable("globalSubscriberId") //globalCustomerId
177 String serviceModelInfo = execution.getVariable("serviceModelInfo")
178 def modelInvariantUuid = ""
179 def modelVersion = ""
182 if (!isBlank(serviceModelInfo))
184 modelInvariantUuid = jsonUtil.getJsonValue(serviceModelInfo, "modelInvariantUuid")
185 modelVersion = jsonUtil.getJsonValue(serviceModelInfo, "modelVersion")
186 modelUuid = jsonUtil.getJsonValue(serviceModelInfo, "modelUuid")
187 modelName = jsonUtil.getJsonValue(serviceModelInfo, "modelName")
189 if (modelInvariantUuid == null) {
190 modelInvariantUuid = ""
192 if (modelVersion == null) {
195 if (modelUuid == null) {
198 if (modelName == null) {
202 if (serviceInstanceName == null) {
203 serviceInstanceName = ""
205 if (serviceId == null) {
209 def siParamsXml = execution.getVariable("siParamsXml")
210 def serviceType = execution.getVariable("serviceType")
211 if (serviceType == null)
216 def sdncRequestId = UUID.randomUUID().toString()
219 """<sdncadapterworkflow:SDNCAdapterWorkflowRequest xmlns:ns5="http://org.openecomp/mso/request/types/v1"
220 xmlns:sdncadapterworkflow="http://org.openecomp/mso/workflow/schema/v1"
221 xmlns:sdncadapter="http://org.openecomp/workflow/sdnc/adapter/schema/v1">
222 <sdncadapter:RequestHeader>
223 <sdncadapter:RequestId>${sdncRequestId}</sdncadapter:RequestId>
224 <sdncadapter:SvcInstanceId>${serviceInstanceId}</sdncadapter:SvcInstanceId>
225 <sdncadapter:SvcAction>delete</sdncadapter:SvcAction>
226 <sdncadapter:SvcOperation>service-topology-operation</sdncadapter:SvcOperation>
227 <sdncadapter:CallbackUrl>${callbackURL}</sdncadapter:CallbackUrl>
228 <sdncadapter:MsoAction>${serviceType}</sdncadapter:MsoAction>
229 </sdncadapter:RequestHeader>
230 <sdncadapterworkflow:SDNCRequestData>
231 <request-information>
232 <request-id>${requestId}</request-id>
237 <request-action>DeleteServiceInstance</request-action>
238 </request-information>
239 <service-information>
240 <service-id>${serviceId}</service-id>
241 <subscription-service-type>${subscriptionServiceType}</subscription-service-type>
242 <onap-model-information>
243 <model-invariant-uuid>${modelInvariantUuid}</model-invariant-uuid>
244 <model-uuid>${modelUuid}</model-uuid>
245 <model-version>${modelVersion}</model-version>
246 <model-name>${modelName}</model-name>
247 </onap-model-information>
248 <service-instance-id>${serviceInstanceId}</service-instance-id>
250 <global-customer-id>${globalSubscriberId}</global-customer-id>
251 </service-information>
252 <service-request-input>
253 <service-instance-name>${serviceInstanceName}</service-instance-name>
255 </service-request-input>
256 </sdncadapterworkflow:SDNCRequestData>
257 </sdncadapterworkflow:SDNCAdapterWorkflowRequest>"""
259 sdncDelete = utils.formatXml(sdncDelete)
260 def sdncRequestId2 = UUID.randomUUID().toString()
261 String sdncDeactivate = sdncDelete.replace(">delete<", ">deactivate<").replace(">${sdncRequestId}<", ">${sdncRequestId2}<")
262 execution.setVariable("sdncDelete", sdncDelete)
263 execution.setVariable("sdncDeactivate", sdncDeactivate)
264 utils.log("INFO","sdncDeactivate:\n" + sdncDeactivate, isDebugEnabled)
265 utils.log("INFO","sdncDelete:\n" + sdncDelete, isDebugEnabled)
267 } catch (BpmnError e) {
269 } catch(Exception ex) {
270 msg = "Exception in preProcessSDNCDelete. " + ex.getMessage()
271 utils.log("INFO", msg, isDebugEnabled)
272 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, "Exception Occured in preProcessSDNCDelete.\n" + ex.getMessage())
274 utils.log("INFO"," *****Exit preProcessSDNCDelete *****", isDebugEnabled)
277 public void postProcessSDNCDelete(Execution execution, String response, String method) {
279 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
280 utils.log("INFO"," ***** postProcessSDNC " + method + " *****", isDebugEnabled)
284 WorkflowException workflowException = execution.getVariable("WorkflowException")
285 boolean successIndicator = execution.getVariable("SDNCA_SuccessIndicator")
286 utils.log("INFO", "SDNCResponse: " + response, isDebugEnabled)
287 utils.log("INFO", "workflowException: " + workflowException, isDebugEnabled)
289 SDNCAdapterUtils sdncAdapterUtils = new SDNCAdapterUtils(this)
290 sdncAdapterUtils.validateSDNCResponse(execution, response, workflowException, successIndicator)
291 if(execution.getVariable(Prefix + 'sdncResponseSuccess') == "true"){
292 utils.log("INFO","Good response from SDNC Adapter for service-instance " + method + "response:\n" + response, isDebugEnabled)
295 msg = "Bad Response from SDNC Adapter for service-instance " + method
296 utils.log("INFO", msg, isDebugEnabled)
297 exceptionUtil.buildAndThrowWorkflowException(execution, 3500, msg)
299 } catch (BpmnError e) {
301 } catch(Exception ex) {
302 msg = "Exception in postProcessSDNC " + method + " Exception:" + ex.getMessage()
303 utils.log("INFO", msg, isDebugEnabled)
304 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
306 utils.log("INFO"," *** Exit postProcessSDNC " + method + " ***", isDebugEnabled)
309 public void postProcessAAIGET(Execution execution) {
310 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
311 utils.log("INFO"," ***** postProcessAAIGET ***** ", isDebugEnabled)
315 String serviceInstanceId = execution.getVariable("serviceInstanceId")
316 boolean foundInAAI = execution.getVariable("GENGS_FoundIndicator")
317 String serviceType = ""
319 if(foundInAAI == true){
320 utils.log("INFO","Found Service-instance in AAI", isDebugEnabled)
322 String siData = execution.getVariable("GENGS_service")
323 utils.log("INFO", "SI Data", isDebugEnabled)
326 msg = "Could not retrive ServiceInstance data from AAI to delete id:" + serviceInstanceId
327 utils.log("INFO", msg, isDebugEnabled)
328 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
332 utils.log("INFO", "SI Data" + siData, isDebugEnabled)
333 //Confirm there are no related service instances (vnf/network or volume)
334 if (utils.nodeExists(siData, "relationship-list")) {
335 utils.log("INFO", "SI Data relationship-list exists:", isDebugEnabled)
336 InputSource source = new InputSource(new StringReader(siData));
337 DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
338 DocumentBuilder docBuilder = docFactory.newDocumentBuilder()
339 Document serviceXml = docBuilder.parse(source)
340 serviceXml.getDocumentElement().normalize()
342 NodeList nodeList = serviceXml.getElementsByTagName("relationship")
343 JSONArray jArray = new JSONArray()
344 for (int x = 0; x < nodeList.getLength(); x++) {
345 Node node = nodeList.item(x)
346 if (node.getNodeType() == Node.ELEMENT_NODE) {
347 Element eElement = (Element) node
348 def e = eElement.getElementsByTagName("related-to").item(0).getTextContent() //for ns
349 if(e.equals("service-instance")){
350 def relatedObject = eElement.getElementsByTagName("related-link").item(0).getTextContent()
351 utils.log("INFO", "ServiceInstance Related NS :" + relatedObject, isDebugEnabled)
352 NodeList dataList = node.getChildNodes()
353 if(null != dataList) {
354 JSONObject jObj = new JSONObject()
355 for (int i = 0; i < dataList.getLength(); i++) {
356 Node dNode = dataList.item(i)
357 if(dNode.getNodeName() == "relationship-data") {
358 Element rDataEle = (Element)dNode
359 def eKey = rDataEle.getElementsByTagName("relationship-key").item(0).getTextContent()
360 def eValue = rDataEle.getElementsByTagName("relationship-value").item(0).getTextContent()
361 if(eKey.equals("service-instance.service-instance-id")){
362 jObj.put("resourceInstanceId", eValue)
365 else if(dNode.getNodeName() == "related-to-property"){
366 Element rDataEle = (Element)dNode
367 def eKey = rDataEle.getElementsByTagName("property-key").item(0).getTextContent()
368 def eValue = rDataEle.getElementsByTagName("property-value").item(0).getTextContent()
369 if(eKey.equals("service-instance.service-instance-name")){
370 jObj.put("resourceType", eValue)
374 utils.log("INFO", "Relationship related to Resource:" + jObj.toString(), isDebugEnabled)
377 //for overlay/underlay
378 }else if (e.equals("configuration")){
379 def relatedObject = eElement.getElementsByTagName("related-link").item(0).getTextContent()
380 utils.log("INFO", "ServiceInstance Related Configuration :" + relatedObject, isDebugEnabled)
381 NodeList dataList = node.getChildNodes()
382 if(null != dataList) {
383 JSONObject jObj = new JSONObject()
384 for (int i = 0; i < dataList.getLength(); i++) {
385 Node dNode = dataList.item(i)
386 if(dNode.getNodeName() == "relationship-data") {
387 Element rDataEle = (Element)dNode
388 def eKey = rDataEle.getElementsByTagName("relationship-key").item(0).getTextContent()
389 def eValue = rDataEle.getElementsByTagName("relationship-value").item(0).getTextContent()
390 if(eKey.equals("configuration.configuration-id")){
391 jObj.put("resourceInstanceId", eValue)
394 else if(dNode.getNodeName() == "related-to-property"){
395 Element rDataEle = (Element)dNode
396 def eKey = rDataEle.getElementsByTagName("property-key").item(0).getTextContent()
397 def eValue = rDataEle.getElementsByTagName("property-value").item(0).getTextContent()
398 if(eKey.equals("configuration.configuration-type")){
399 jObj.put("resourceType", eValue)
403 utils.log("INFO", "Relationship related to Resource:" + jObj.toString(), isDebugEnabled)
409 execution.setVariable("serviceRelationShip", jArray.toString())
413 boolean succInAAI = execution.getVariable("GENGS_SuccessIndicator")
414 if(succInAAI != true){
415 utils.log("INFO","Error getting Service-instance from AAI", + serviceInstanceId, isDebugEnabled)
416 WorkflowException workflowException = execution.getVariable("WorkflowException")
417 utils.logAudit("workflowException: " + workflowException)
418 if(workflowException != null){
419 exceptionUtil.buildAndThrowWorkflowException(execution, workflowException.getErrorCode(), workflowException.getErrorMessage())
423 msg = "Failure in postProcessAAIGET GENGS_SuccessIndicator:" + succInAAI
424 utils.log("INFO", msg, isDebugEnabled)
425 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, msg)
429 utils.log("INFO","Service-instance NOT found in AAI. Silent Success", isDebugEnabled)
431 }catch (BpmnError e) {
433 } catch (Exception ex) {
434 msg = "Exception in DoDeleteE2EServiceInstance.postProcessAAIGET. " + ex.getMessage()
435 utils.log("INFO", msg, isDebugEnabled)
436 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
438 utils.log("INFO"," *** Exit postProcessAAIGET *** ", isDebugEnabled)
441 public void postProcessAAIDEL(Execution execution) {
442 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
443 utils.log("INFO"," ***** postProcessAAIDEL ***** ", isDebugEnabled)
446 String serviceInstanceId = execution.getVariable("serviceInstanceId")
447 boolean succInAAI = execution.getVariable("GENDS_SuccessIndicator")
448 if(succInAAI != true){
449 msg = "Error deleting Service-instance in AAI" + serviceInstanceId
450 utils.log("INFO", msg, isDebugEnabled)
451 WorkflowException workflowException = execution.getVariable("WorkflowException")
452 utils.logAudit("workflowException: " + workflowException)
453 if(workflowException != null){
454 exceptionUtil.buildAndThrowWorkflowException(execution, workflowException.getErrorCode(), workflowException.getErrorMessage())
458 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, msg)
461 } catch (BpmnError e) {
463 } catch (Exception ex) {
464 msg = "Exception in DoDeleteE2EServiceInstance.postProcessAAIDEL. " + ex.getMessage()
465 utils.log("INFO", msg, isDebugEnabled)
466 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
468 utils.log("INFO"," *** Exit postProcessAAIDEL *** ", isDebugEnabled)
471 public void preInitResourcesOperStatus(Execution execution){
472 def isDebugEnabled = execution.getVariable("isDebugLogEnabled")
474 utils.log("INFO", " ======== STARTED preInitResourcesOperStatus Process ======== ", isDebugEnabled)
476 String serviceId = execution.getVariable("serviceInstanceId")
477 String operationId = execution.getVariable("operationId")
478 String operationType = execution.getVariable("operationType")
479 String resourceTemplateUUIDs = ""
480 String result = "processing"
481 String progress = "0"
483 String operationContent = "Prepare service creation"
484 utils.log("INFO", "Generated new operation for Service Instance serviceId:" + serviceId + " operationId:" + operationId + " operationType:" + operationType, isDebugEnabled)
485 serviceId = UriUtils.encode(serviceId,"UTF-8")
486 execution.setVariable("serviceInstanceId", serviceId)
487 execution.setVariable("operationId", operationId)
488 execution.setVariable("operationType", operationType)
489 // we use resource instance ids for delete flow as resourceTemplateUUIDs
492 "resourceInstanceId":"1111",
493 "resourceType":"vIMS"
496 "resourceInstanceId":"222",
497 "resourceType":"vEPC"
500 "resourceInstanceId":"3333",
501 "resourceType":"overlay"
504 "resourceInstanceId":"4444",
505 "resourceType":"underlay"
508 String serviceRelationShip = execution.getVariable("serviceRelationShip")
510 def jsonSlurper = new JsonSlurper()
511 def jsonOutput = new JsonOutput()
512 List relationShipList = jsonSlurper.parseText(serviceRelationShip)
514 if (relationShipList != null) {
515 relationShipList.each {
516 resourceTemplateUUIDs = resourceTemplateUUIDs + it.resourceInstanceId + ":"
519 execution.setVariable("URN_mso_openecomp_adapters_db_endpoint","http://mso.mso.testlab.openecomp.org:8080/dbadapters/RequestsDbAdapter")
522 """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
523 xmlns:ns="http://org.openecomp.mso/requestsdb">
526 <ns:initResourceOperationStatus xmlns:ns="http://org.openecomp.mso/requestsdb">
527 <serviceId>${serviceId}</serviceId>
528 <operationId>${operationId}</operationId>
529 <operationType>${operationType}</operationType>
530 <resourceTemplateUUIDs>${resourceTemplateUUIDs}</resourceTemplateUUIDs>
531 </ns:initResourceOperationStatus>
533 </soapenv:Envelope>"""
535 payload = utils.formatXml(payload)
536 execution.setVariable("CVFMI_initResOperStatusRequest", payload)
537 utils.log("INFO", "Outgoing initResourceOperationStatus: \n" + payload, isDebugEnabled)
538 utils.logAudit("CreateVfModuleInfra Outgoing initResourceOperationStatus Request: " + payload)
541 utils.log("ERROR", "Exception Occured Processing preInitResourcesOperStatus. Exception is:\n" + e, isDebugEnabled)
542 execution.setVariable("CVFMI_ErrorResponse", "Error Occurred during preInitResourcesOperStatus Method:\n" + e.getMessage())
544 utils.log("INFO", "======== COMPLETED preInitResourcesOperStatus Process ======== ", isDebugEnabled)
548 * prepare delete parameters
550 public void preResourceDelete(execution, resourceName){
551 // we use resource instance ids for delete flow as resourceTemplateUUIDs
554 "resourceInstanceId":"1111",
555 "resourceType":"vIMS"
558 "resourceInstanceId":"222",
559 "resourceType":"vEPC"
562 "resourceInstanceId":"3333",
563 "resourceType":"overlay"
566 "resourceInstanceId":"4444",
567 "resourceType":"underlay"
570 def isDebugEnabled = execution.getVariable("isDebugLogEnabled")
572 utils.log("INFO", " ======== STARTED preResourceDelete Process ======== ", isDebugEnabled)
573 String serviceRelationShip = execution.getVariable("serviceRelationShip")
574 def jsonSlurper = new JsonSlurper()
575 def jsonOutput = new JsonOutput()
576 List relationShipList = jsonSlurper.parseText(serviceRelationShip)
578 if (relationShipList != null) {
579 relationShipList.each {
580 if(StringUtils.containsIgnoreCase(it.resourceType, resourceName)) {
581 String resourceInstanceUUID = it.resourceInstanceId
582 String resourceTemplateUUID = it.resourceInstanceId
583 execution.setVariable("resourceTemplateId", resourceTemplateUUID)
584 execution.setVariable("resourceInstanceId", resourceInstanceUUID)
585 execution.setVariable("resourceType", resourceName)
586 utils.log("INFO", "Delete Resource Info resourceTemplate Id :" + resourceTemplateUUID + " resourceInstanceId: " + resourceInstanceUUID + " resourceType: " + resourceName, isDebugEnabled)
590 utils.log("INFO", " ======== END preResourceDelete Process ======== ", isDebugEnabled)