2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
20 package org.onap.so.bpmn.infrastructure.scripts
22 import org.onap.so.logger.MsoLogger
24 import static org.apache.commons.lang3.StringUtils.*;
26 import javax.ws.rs.core.Response
27 import javax.xml.parsers.DocumentBuilder
28 import javax.xml.parsers.DocumentBuilderFactory
30 import org.apache.commons.lang3.*
31 import org.camunda.bpm.engine.delegate.BpmnError
32 import org.camunda.bpm.engine.delegate.DelegateExecution
33 import org.json.JSONArray
34 import org.json.JSONObject
36 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor
37 import org.onap.so.bpmn.common.scripts.ExceptionUtil
38 import org.onap.so.bpmn.common.scripts.MsoUtils
39 import org.onap.so.bpmn.core.WorkflowException
40 import org.onap.so.bpmn.core.domain.Resource
41 import org.onap.so.bpmn.core.domain.ServiceDecomposition
42 import org.onap.so.bpmn.core.UrnPropertiesReader
44 import org.onap.so.utils.TargetEntity
45 import org.onap.so.bpmn.core.json.JsonUtils
46 import org.onap.so.client.HttpClient
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
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
70 * @param - delResourceList
71 * @param - serviceRelationShip
74 * @param - WorkflowException
78 public class DoDeleteE2EServiceInstance extends AbstractServiceTaskProcessor {
80 String Prefix="DDEESI_"
81 ExceptionUtil exceptionUtil = new ExceptionUtil()
82 JsonUtils jsonUtil = new JsonUtils()
83 private static final MsoLogger msoLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.BPEL, DoDeleteE2EServiceInstance.class);
86 public void preProcessRequest (DelegateExecution execution) {
87 msoLogger.debug(" ***** preProcessRequest *****")
91 String requestId = execution.getVariable("msoRequestId")
92 execution.setVariable("prefix",Prefix)
95 //requestDetails.subscriberInfo. for AAI GET & PUT & SDNC assignToplology
96 String globalSubscriberId = execution.getVariable("globalSubscriberId") //globalCustomerId
97 if (globalSubscriberId == null)
99 execution.setVariable("globalSubscriberId", "")
102 //requestDetails.requestParameters. for AAI PUT & SDNC assignTopology
103 String serviceType = execution.getVariable("serviceType")
104 if (serviceType == null)
106 execution.setVariable("serviceType", "")
109 //Generated in parent for AAI PUT
110 String serviceInstanceId = execution.getVariable("serviceInstanceId")
111 if (isBlank(serviceInstanceId)){
112 msg = "Input serviceInstanceId is null"
114 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
117 String sdncCallbackUrl = UrnPropertiesReader.getVariable('URN_mso_workflow_sdncadapter_callback', execution)
118 if (isBlank(sdncCallbackUrl)) {
119 msg = "URN_mso_workflow_sdncadapter_callback is null"
121 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
123 execution.setVariable("sdncCallbackUrl", sdncCallbackUrl)
124 msoLogger.info("SDNC Callback URL: " + sdncCallbackUrl)
126 StringBuilder sbParams = new StringBuilder()
127 Map<String, String> paramsMap = execution.getVariable("serviceInputParams")
129 if (paramsMap != null) {
130 sbParams.append("<service-input-parameters>")
131 for (Map.Entry<String, String> entry : paramsMap.entrySet()) {
133 String paramName = entry.getKey()
134 String paramValue = entry.getValue()
137 <name>${MsoUtils.xmlEscape(paramName)}</name>
138 <value>${MsoUtils.xmlEscape(paramValue)}</value>
141 sbParams.append(paramsXml)
143 sbParams.append("</service-input-parameters>")
145 String siParamsXml = sbParams.toString()
146 if (siParamsXml == null)
148 execution.setVariable("siParamsXml", siParamsXml)
150 } catch (BpmnError e) {
152 } catch (Exception ex){
153 msg = "Exception in preProcessRequest " + ex.getMessage()
155 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
157 msoLogger.debug("***** Exit preProcessRequest *****")
160 public void postProcessAAIGET(DelegateExecution execution) {
161 msoLogger.debug(" ***** postProcessAAIGET ***** ")
165 String serviceInstanceId = execution.getVariable("serviceInstanceId")
166 boolean foundInAAI = execution.getVariable("GENGS_FoundIndicator")
167 String serviceType = ""
170 msoLogger.debug("Found Service-instance in AAI")
172 String siData = execution.getVariable("GENGS_service")
173 msoLogger.debug("SI Data")
176 msg = "Could not retrive ServiceInstance data from AAI to delete id:" + serviceInstanceId
178 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
182 InputSource source = new InputSource(new StringReader(siData));
183 DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
184 DocumentBuilder docBuilder = docFactory.newDocumentBuilder()
185 Document serviceXml = docBuilder.parse(source)
186 serviceXml.getDocumentElement().normalize()
187 // get model invariant id
188 // Get Template uuid and version
189 if (utils.nodeExists(siData, "model-invariant-id") && utils.nodeExists(siData, "model-version-id") ) {
190 msoLogger.debug("SI Data model-invariant-id and model-version-id exist")
191 def modelInvariantId = serviceXml.getElementsByTagName("model-invariant-id").item(0).getTextContent()
192 def modelVersionId = serviceXml.getElementsByTagName("model-version-id").item(0).getTextContent()
194 // Set Original Template info
195 execution.setVariable("model-invariant-id-original", modelInvariantId)
196 execution.setVariable("model-version-id-original", modelVersionId)
199 msoLogger.debug("SI Data" + siData)
200 //Confirm there are no related service instances (vnf/network or volume)
201 if (utils.nodeExists(siData, "relationship-list")) {
202 msoLogger.debug("SI Data relationship-list exists")
203 JSONArray jArray = new JSONArray()
205 XmlParser xmlParser = new XmlParser()
206 Node root = xmlParser.parseText(siData)
207 def relation_list = utils.getChildNode(root, 'relationship-list')
208 def relationships = utils.getIdenticalChildren(relation_list, 'relationship')
210 for (def relation: relationships) {
211 def jObj = getRelationShipData(relation, isDebugEnabled)
215 execution.setVariable("serviceRelationShip", jArray.toString())
216 execution.setVariable("serviceRelationShip", jArray.toString())
220 boolean succInAAI = execution.getVariable("GENGS_SuccessIndicator")
222 msoLogger.debug("Error getting Service-instance from AAI :" + serviceInstanceId)
223 WorkflowException workflowException = execution.getVariable("WorkflowException")
224 if(workflowException != null){
225 msoLogger.error("workflowException: " + workflowException)
226 exceptionUtil.buildAndThrowWorkflowException(execution, workflowException.getErrorCode(), workflowException.getErrorMessage())
229 msg = "Failure in postProcessAAIGET GENGS_SuccessIndicator:" + succInAAI
231 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, msg)
235 msoLogger.debug("Service-instance NOT found in AAI. Silent Success")
237 }catch (BpmnError e) {
239 } catch (Exception ex) {
240 msg = "Exception in DoDeleteE2EServiceInstance.postProcessAAIGET. " + ex.getMessage()
242 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
244 msoLogger.debug(" *** Exit postProcessAAIGET *** ")
247 private JSONObject getRelationShipData(node, isDebugEnabled){
248 JSONObject jObj = new JSONObject()
250 def relation = utils.nodeToString(node)
251 def rt = utils.getNodeText(relation, "related-to")
253 def rl = utils.getNodeText(relation, "related-link")
254 msoLogger.debug("ServiceInstance Related NS/Configuration :" + rl)
256 def rl_datas = utils.getIdenticalChildren(node, "relationship-data")
257 for(def rl_data : rl_datas) {
258 def eKey = utils.getChildNodeText(rl_data, "relationship-key")
259 def eValue = utils.getChildNodeText(rl_data, "relationship-value")
261 if ((rt == "service-instance" && eKey.equals("service-instance.service-instance-id"))
262 //for overlay/underlay
263 || (rt == "configuration" && eKey.equals("configuration.configuration-id")
265 jObj.put("resourceInstanceId", eValue)
267 // for sp-partner and others
268 else if(eKey.endsWith("-id")){
269 jObj.put("resourceInstanceId", eValue)
270 String resourceName = rt + eValue;
271 jObj.put("resourceType", resourceName)
274 jObj.put("resourceLinkUrl", rl)
277 def rl_props = utils.getIdenticalChildren(node, "related-to-property")
278 for(def rl_prop : rl_props) {
279 def eKey = utils.getChildNodeText(rl_prop, "property-key")
280 def eValue = utils.getChildNodeText(rl_prop, "property-value")
281 if((rt == "service-instance" && eKey.equals("service-instance.service-instance-name"))
282 //for overlay/underlay
283 || (rt == "configuration" && eKey.equals("configuration.configuration-type"))){
284 jObj.put("resourceType", eValue)
288 msoLogger.debug("Relationship related to Resource:" + jObj.toString())
292 public void getCurrentNS(DelegateExecution execution){
293 utils.log("INFO", "======== Start getCurrentNS Process ======== ", isDebugEnabled)
295 def currentIndex = execution.getVariable("currentNSIndex")
296 List<String> nsSequence = execution.getVariable("nsSequence")
297 String nsResourceType = nsSequence.get(currentIndex)
299 // GET AAI by Name, not ID, for process convenient
300 execution.setVariable("GENGS_type", "service-instance")
301 execution.setVariable("GENGS_serviceInstanceId", "")
302 execution.setVariable("GENGS_serviceInstanceName", nsResourceType)
304 msoLogger.debug("======== COMPLETED getCurrentNS Process ======== ")
307 public void prepareDecomposeService(DelegateExecution execution) {
309 msoLogger.debug(" ***** Inside prepareDecomposeService of create generic e2e service ***** ")
310 String modelInvariantUuid = execution.getVariable("model-invariant-id-original")
311 String modelVersionId = execution.getVariable("model-version-id-original")
313 String serviceModelInfo = """{
314 "modelInvariantUuid":"${modelInvariantUuid}",
315 "modelUuid":"${modelVersionId}",
318 execution.setVariable("serviceModelInfo", serviceModelInfo)
320 msoLogger.debug(" ***** Completed prepareDecomposeService of create generic e2e service ***** ")
321 } catch (Exception ex) {
322 // try error in method block
323 String exceptionMessage = "Bpmn error encountered in create generic e2e service flow. Unexpected Error from method prepareDecomposeService() - " + ex.getMessage()
324 msoLogger.error(exceptionMessage)
325 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, exceptionMessage)
329 private void generateRelatedResourceInfo(String response, JSONObject jObj){
331 def xml = new XmlSlurper().parseText(response)
332 def rtn = xml.childNodes()
333 while (rtn.hasNext()) {
334 groovy.util.slurpersupport.Node node = rtn.next()
335 def key = node.name()
336 def value = node.text()
341 private JSONObject getRelatedResourceInAAI (DelegateExecution execution, JSONObject jObj)
343 msoLogger.debug(" ***** Started getRelatedResourceInAAI *****")
345 String aai_endpoint = UrnPropertiesReader.getVariable("aai.endpoint", execution)
346 String urlLink = jObj.get("resourceLinkUrl")
347 String serviceAaiPath = "${aai_endpoint}${urlLink}"
349 URL url = new URL(serviceAaiPath)
350 HttpClient client = new HttpClient(url, "application/xml", TargetEntity.AAI)
353 Response response = client.get()
354 int responseCode = response.getStatus()
355 execution.setVariable(Prefix + "GeRelatedResourceResponseCode", responseCode)
356 msoLogger.debug(" Get RelatedResource code is: " + responseCode)
358 String aaiResponse = response.readEntity(String.class)
359 execution.setVariable(Prefix + "GetRelatedResourceResponse", aaiResponse)
362 if(responseCode == 200 || responseCode == 201 || responseCode == 202 )
363 //200 OK 201 CREATED 202 ACCEPTED
365 msoLogger.debug("GET RelatedResource Received a Good Response")
366 execution.setVariable(Prefix + "SuccessIndicator", true)
367 execution.setVariable(Prefix + "FoundIndicator", true)
369 generateRelatedResourceInfo(aaiResponse, jObj)
371 //get model-invariant-uuid and model-uuid
372 String modelInvariantId = ""
373 String modelUuid = ""
374 String modelCustomizationId = ""
375 if(jObj.has("model-invariant-id")) {
376 modelInvariantId = jObj.get("model-invariant-id")
377 modelUuid = jObj.get("model-version-id")
378 modelCustomizationId = jObj.get("model-customization-id")
381 jObj.put("modelInvariantId", modelInvariantId)
382 jObj.put("modelVersionId", modelUuid)
383 jObj.put("modelCustomizationId", modelCustomizationId)
386 String exceptionMessage = "Get RelatedResource Received a Bad Response Code. Response Code is: " + responseCode
387 msoLogger.error(exceptionMessage)
388 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, exceptionMessage)
391 msoLogger.debug(" ***** Exit getRelatedResourceInAAI *****")
395 public void postDecomposeService(DelegateExecution execution) {
396 msoLogger.debug(" ***** Inside processDecomposition() of delete generic e2e service flow ***** ")
398 ServiceDecomposition serviceDecomposition = execution.getVariable("serviceDecomposition")
400 // service model info
401 execution.setVariable("serviceModelInfo", serviceDecomposition.getModelInfo())
403 List<Resource> deleteResourceList = serviceDecomposition.getServiceResources()
404 String serviceRelationShip = execution.getVariable("serviceRelationShip")
405 def jsonSlurper = new JsonSlurper()
406 def jsonOutput = new JsonOutput()
408 List relationShipList = null
409 if (serviceRelationShip != null) {
410 relationShipList = jsonSlurper.parseText(serviceRelationShip)
413 List<Resource> deleteRealResourceList = new ArrayList<Resource>()
415 //Set the real resource instance id to the decomosed resource list
416 //reset the resource instance id , because in the decompose flow ,its a random one.
417 //match the resource-instance-name and the model name
418 if (relationShipList != null) {
419 relationShipList.each {
421 JSONObject obj = getRelatedResourceInAAI(execution, (JSONObject)it)
423 for (Resource resource : deleteResourceList) {
425 String modelName = resource.getModelInfo().getModelName()
427 String modelCustomizationUuid = resource.getModelInfo().getModelCustomizationUuid()
428 if (StringUtils.containsIgnoreCase(obj.get("resourceType"), modelName)) {
429 resource.setResourceId(obj.get("resourceInstanceId"))
430 deleteRealResourceList.add(resource)
432 else if (modelCustomizationUuid.equals(obj.get("modelCustomizationId"))) {
433 resource.setResourceId(obj.get("resourceInstanceId"))
434 resource.setResourceInstanceName(obj.get("resourceType"))
435 deleteRealResourceList.add(resource)
441 // only delete real existing resources
442 execution.setVariable("deleteResourceList", deleteRealResourceList)
444 boolean isDeleteResourceListValid = false
445 if(deleteRealResourceList.size() > 0) {
446 isDeleteResourceListValid = true
448 execution.setVariable("isDeleteResourceListValid", isDeleteResourceListValid)
450 msoLogger.debug("delete resource list : " + deleteRealResourceList)
451 } catch (Exception ex) {
452 String exceptionMessage = "Bpmn error encountered in create generic e2e service flow. processDecomposition() - " + ex.getMessage()
453 msoLogger.error(exceptionMessage)
454 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, exceptionMessage)
456 utils.log("DEBUG", " ***** exit processDecomposition() of delete generic e2e service flow ***** ", isDebugEnabled)
459 public void preInitResourcesOperStatus(DelegateExecution execution){
460 msoLogger.debug(" ======== STARTED preInitResourcesOperStatus Process ======== ")
462 String serviceId = execution.getVariable("serviceInstanceId")
463 String operationId = execution.getVariable("operationId")
464 String operationType = execution.getVariable("operationType")
465 String resourceTemplateUUIDs = ""
466 String result = "processing"
467 String progress = "0"
469 String operationContent = "Prepare service creation"
470 msoLogger.debug("Generated new operation for Service Instance serviceId:" + serviceId + " operationId:" + operationId + " operationType:" + operationType)
471 serviceId = UriUtils.encode(serviceId,"UTF-8")
472 execution.setVariable("serviceInstanceId", serviceId)
473 execution.setVariable("operationId", operationId)
474 execution.setVariable("operationType", operationType)
475 List<Resource> deleteResourceList = execution.getVariable("deleteResourceList")
477 String serviceRelationShip = execution.getVariable("serviceRelationShip")
478 for(Resource resource : deleteResourceList){
479 resourceTemplateUUIDs = resourceTemplateUUIDs + resource.getModelInfo().getModelCustomizationUuid() + ":"
482 def dbAdapterEndpoint = UrnPropertiesReader.getVariable("mso.adapters.openecomp.db.endpoint", execution)
483 execution.setVariable("URN_mso_adapters_openecomp_db_endpoint", dbAdapterEndpoint)
486 """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
487 xmlns:ns="http://org.onap.so/requestsdb">
490 <ns:initResourceOperationStatus xmlns:ns="http://org.onap.so/requestsdb">
491 <serviceId>${MsoUtils.xmlEscape(serviceId)}</serviceId>
492 <operationId>${MsoUtils.xmlEscape(operationId)}</operationId>
493 <operationType>${MsoUtils.xmlEscape(operationType)}</operationType>
494 <resourceTemplateUUIDs>${MsoUtils.xmlEscape(resourceTemplateUUIDs)}</resourceTemplateUUIDs>
495 </ns:initResourceOperationStatus>
497 </soapenv:Envelope>"""
499 payload = utils.formatXml(payload)
500 execution.setVariable("CVFMI_initResOperStatusRequest", payload)
501 msoLogger.debug("Outgoing initResourceOperationStatus: \n" + payload)
502 msoLogger.debug("CreateVfModuleInfra Outgoing initResourceOperationStatus Request: " + payload)
505 msoLogger.debug("Exception Occured Processing preInitResourcesOperStatus. Exception is:\n" + e)
506 execution.setVariable("CVFMI_ErrorResponse", "Error Occurred during preInitResourcesOperStatus Method:\n" + e.getMessage())
508 msoLogger.debug("======== COMPLETED preInitResourcesOperStatus Process ======== ")
511 public void prepareUpdateServiceOperationStatus(DelegateExecution execution){
512 msoLogger.debug(" ======== STARTED prepareUpdateServiceOperationStatus Process ======== ")
514 String serviceId = execution.getVariable("serviceInstanceId")
515 String operationId = execution.getVariable("operationId")
517 String result = execution.getVariable("result")
518 String progress = execution.getVariable("progress")
520 String operationContent = execution.getVariable("operationContent")
522 serviceId = UriUtils.encode(serviceId,"UTF-8")
524 def dbAdapterEndpoint = UrnPropertiesReader.getVariable("mso.adapters.openecomp.db.endpoint", execution)
525 execution.setVariable("CVFMI_dbAdapterEndpoint", dbAdapterEndpoint)
526 msoLogger.debug("DB Adapter Endpoint is: " + dbAdapterEndpoint)
529 """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
530 xmlns:ns="http://org.onap.so/requestsdb">
533 <ns:updateServiceOperationStatus xmlns:ns="http://org.onap.so/requestsdb">
534 <serviceId>${MsoUtils.xmlEscape(serviceId)}</serviceId>
535 <operationId>${MsoUtils.xmlEscape(operationId)}</operationId>
536 <operationType>DELETE</operationType>
537 <userId>${MsoUtils.xmlEscape(userId)}</userId>
538 <result>${MsoUtils.xmlEscape(result)}</result>
539 <operationContent>${MsoUtils.xmlEscape(operationContent)}</operationContent>
540 <progress>${MsoUtils.xmlEscape(progress)}</progress>
541 <reason>${MsoUtils.xmlEscape(reason)}</reason>
542 </ns:updateServiceOperationStatus>
544 </soapenv:Envelope>"""
546 payload = utils.formatXml(payload)
547 execution.setVariable("CVFMI_updateServiceOperStatusRequest", payload)
548 msoLogger.debug("Outgoing updateServiceOperStatusRequest: \n" + payload)
551 msoLogger.error("Exception Occured Processing prepareUpdateServiceOperationStatus. Exception is:\n" + e)
552 execution.setVariable("CVFMI_ErrorResponse", "Error Occurred during prepareUpdateServiceOperationStatus Method:\n" + e.getMessage())
554 msoLogger.debug("======== COMPLETED prepareUpdateServiceOperationStatus Process ======== ")
558 * post config request.
560 public void postConfigRequest(execution){