2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
6 * ================================================================================
7 * Modifications Copyright (c) 2019 Samsung
8 * ================================================================================
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 * ============LICENSE_END=========================================================
22 package org.onap.so.bpmn.infrastructure.scripts
24 import groovy.json.JsonOutput
25 import groovy.json.JsonSlurper
26 import org.apache.commons.lang3.StringUtils
27 import org.camunda.bpm.engine.delegate.BpmnError
28 import org.camunda.bpm.engine.delegate.DelegateExecution
29 import org.json.JSONArray
30 import org.json.JSONObject
31 import org.onap.aai.domain.yang.RelatedToProperty
32 import org.onap.aai.domain.yang.Relationship
33 import org.onap.aai.domain.yang.RelationshipData
34 import org.onap.aai.domain.yang.ServiceInstance
35 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor
36 import org.onap.so.bpmn.common.scripts.ExceptionUtil
37 import org.onap.so.bpmn.common.scripts.MsoUtils
38 import org.onap.so.bpmn.core.UrnPropertiesReader
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.json.JsonUtils
43 import org.onap.so.client.HttpClient
44 import org.onap.so.client.HttpClientFactory
45 import org.onap.so.client.aai.AAIObjectType
46 import org.onap.so.client.aai.AAIResourcesClient
47 import org.onap.so.client.aai.entities.AAIResultWrapper
48 import org.onap.so.client.aai.entities.uri.AAIResourceUri
49 import org.onap.so.client.aai.entities.uri.AAIUriFactory
50 import org.slf4j.Logger
51 import org.slf4j.LoggerFactory
52 import org.onap.so.utils.TargetEntity
53 import org.springframework.web.util.UriUtils
54 import org.w3c.dom.Document
55 import org.w3c.dom.Node
56 import org.xml.sax.InputSource
58 import javax.ws.rs.NotFoundException
59 import javax.ws.rs.core.Response
60 import javax.xml.parsers.DocumentBuilder
61 import javax.xml.parsers.DocumentBuilderFactory
63 import static org.apache.commons.lang3.StringUtils.isBlank
66 * This groovy class supports the <class>DoDeleteE2EServiceInstance.bpmn</class> process.
69 * @param - msoRequestId
70 * @param - globalSubscriberId - O
71 * @param - subscriptionServiceType - O
72 * @param - serviceInstanceId
73 * @param - serviceInstanceName - O
74 * @param - serviceInputParams (should contain aic_zone for serviceTypes TRANSPORT,ATM)
75 * @param - sdncVersion
76 * @param - failNotFound - TODO
77 * @param - serviceInputParams - TODO
79 * @param - delResourceList
80 * @param - serviceRelationShip
83 * @param - WorkflowException
87 public class DoDeleteE2EServiceInstance extends AbstractServiceTaskProcessor {
89 String Prefix="DDEESI_"
90 ExceptionUtil exceptionUtil = new ExceptionUtil()
91 JsonUtils jsonUtil = new JsonUtils()
92 private static final Logger logger = LoggerFactory.getLogger( DoDeleteE2EServiceInstance.class);
95 public void preProcessRequest (DelegateExecution execution) {
96 logger.debug(" ***** preProcessRequest *****")
100 String requestId = execution.getVariable("msoRequestId")
101 execution.setVariable("prefix",Prefix)
104 //requestDetails.subscriberInfo. for AAI GET & PUT & SDNC assignToplology
105 String globalSubscriberId = execution.getVariable("globalSubscriberId") //globalCustomerId
106 if (globalSubscriberId == null)
108 execution.setVariable("globalSubscriberId", "")
111 //requestDetails.requestParameters. for AAI PUT & SDNC assignTopology
112 String serviceType = execution.getVariable("serviceType")
113 if (serviceType == null)
115 execution.setVariable("serviceType", "")
118 //Generated in parent for AAI PUT
119 String serviceInstanceId = execution.getVariable("serviceInstanceId")
120 if (isBlank(serviceInstanceId)){
121 msg = "Input serviceInstanceId is null"
123 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
126 String sdncCallbackUrl = UrnPropertiesReader.getVariable('mso.workflow.sdncadapter.callback', execution)
127 if (isBlank(sdncCallbackUrl)) {
128 msg = "URN_mso_workflow_sdncadapter_callback is null"
130 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
132 execution.setVariable("sdncCallbackUrl", sdncCallbackUrl)
133 logger.info("SDNC Callback URL: " + sdncCallbackUrl)
135 StringBuilder sbParams = new StringBuilder()
136 Map<String, String> paramsMap = execution.getVariable("serviceInputParams")
138 if (paramsMap != null) {
139 sbParams.append("<service-input-parameters>")
140 for (Map.Entry<String, String> entry : paramsMap.entrySet()) {
142 String paramName = entry.getKey()
143 String paramValue = entry.getValue()
146 <name>${MsoUtils.xmlEscape(paramName)}</name>
147 <value>${MsoUtils.xmlEscape(paramValue)}</value>
150 sbParams.append(paramsXml)
152 sbParams.append("</service-input-parameters>")
154 String siParamsXml = sbParams.toString()
155 if (siParamsXml == null)
157 execution.setVariable("siParamsXml", siParamsXml)
159 } catch (BpmnError e) {
161 } catch (Exception ex){
162 msg = "Exception in preProcessRequest " + ex.getMessage()
164 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
166 logger.debug("***** Exit preProcessRequest *****")
169 public void postProcessAAIGET(DelegateExecution execution) {
170 logger.debug(" ***** postProcessAAIGET ***** ")
175 String serviceInstanceId = execution.getVariable('serviceInstanceId')
176 String globalSubscriberId = execution.getVariable('globalSubscriberId')
177 String serviceType = execution.getVariable('serviceType')
180 AAIResourcesClient resourceClient = new AAIResourcesClient()
181 AAIResourceUri serviceInstanceUri = AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE, globalSubscriberId, serviceType, serviceInstanceId)
183 if (!resourceClient.exists(serviceInstanceUri)) {
184 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Service Instance was not found in aai")
187 AAIResultWrapper wrapper = resourceClient.get(serviceInstanceUri, NotFoundException.class)
189 Optional<ServiceInstance> si = wrapper.asBean(ServiceInstance.class)
192 if (si.isPresent() && StringUtils.isNotEmpty(si.get().getServiceInstanceName())) {
193 logger.debug("Found Service-instance in AAI")
194 execution.setVariable("serviceInstanceName", si.get().getServiceInstanceName())
195 // get model invariant id
196 // Get Template uuid and version
197 if ((null != si.get().getModelInvariantId()) && (null != si.get().getModelVersionId())) {
198 logger.debug("SI Data model-invariant-id and model-version-id exist")
200 // Set Original Template info
201 execution.setVariable("model-invariant-id-original", si.get().getModelInvariantId())
202 execution.setVariable("model-version-id-original", si.get().getModelVersionId())
205 if ((null != si.get().getRelationshipList()) && (null != si.get().getRelationshipList().getRelationship())) {
206 logger.debug("SI Data relationship-list exists")
207 List<Relationship> relationshipList = si.get().getRelationshipList().getRelationship()
208 JSONArray jArray = new JSONArray()
209 for (Relationship relationship : relationshipList) {
210 def jObj = getRelationShipData(relationship)
214 execution.setVariable("serviceRelationShip", jArray.toString())
219 msg = "Service-instance: " + serviceInstanceId + " NOT found in AAI."
221 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, msg)
223 } catch (BpmnError e) {
225 } catch (NotFoundException e) {
226 logger.debug("Service Instance does not exist AAI")
227 exceptionUtil.buildAndThrowWorkflowException(execution, 404, "Service Instance was not found in aai")
228 } catch (Exception ex) {
229 msg = "Exception in DoDeleteE2EServiceInstance.postProcessAAIGET. " + ex.getMessage()
231 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
233 logger.debug(" *** Exit postProcessAAIGET *** ")
236 private JSONObject getRelationShipData(Relationship relationship) {
237 JSONObject jObj = new JSONObject()
240 def rt = relationship.getRelatedTo()
242 def rl = relationship.getRelatedLink()
243 logger.debug("ServiceInstance Related NS/Configuration :" + rl)
245 List<RelationshipData> rl_datas = relationship.getRelationshipData()
246 for (RelationshipData rl_data : rl_datas) {
247 def eKey = rl_data.getRelationshipKey()
248 def eValue = rl_data.getRelationshipValue()
250 if ((rt.equals("service-instance") && eKey.equals("service-instance.service-instance-id"))
251 //for overlay/underlay
252 || (rt.equals("configuration") && eKey.equals("configuration.configuration-id")
254 jObj.put("resourceInstanceId", eValue)
256 // for sp-partner and others
257 else if (eKey.endsWith("-id")) {
258 jObj.put("resourceInstanceId", eValue)
259 String resourceName = rt + eValue;
260 jObj.put("resourceType", resourceName)
263 jObj.put("resourceLinkUrl", rl)
266 List<RelatedToProperty> rl_props = relationship.getRelatedToProperty()
267 for (RelatedToProperty rl_prop : rl_props) {
268 def eKey = rl_prop.getPropertyKey()
269 def eValue = rl_prop.getPropertyValue()
270 if ((rt.equals("service-instance") && eKey.equals("service-instance.service-instance-name"))
271 //for overlay/underlay
272 || (rt.equals("configuration") && eKey.equals("configuration.configuration-type"))) {
273 jObj.put("resourceType", eValue)
277 logger.debug("Relationship related to Resource:" + jObj.toString())
281 public void getCurrentNS(DelegateExecution execution){
282 logger.info( "======== Start getCurrentNS Process ======== ")
284 def currentIndex = execution.getVariable("currentNSIndex")
285 List<String> nsSequence = execution.getVariable("nsSequence")
286 String nsResourceType = nsSequence.get(currentIndex)
288 // GET AAI by Name, not ID, for process convenient
289 execution.setVariable("GENGS_type", "service-instance")
290 execution.setVariable("GENGS_serviceInstanceId", "")
291 execution.setVariable("GENGS_serviceInstanceName", nsResourceType)
293 logger.debug("======== COMPLETED getCurrentNS Process ======== ")
296 public void prepareDecomposeService(DelegateExecution execution) {
298 logger.debug(" ***** Inside prepareDecomposeService of create generic e2e service ***** ")
299 String modelInvariantUuid = execution.getVariable("model-invariant-id-original")
300 String modelVersionId = execution.getVariable("model-version-id-original")
302 String serviceModelInfo = """{
303 "modelInvariantUuid":"${modelInvariantUuid}",
304 "modelUuid":"${modelVersionId}",
307 execution.setVariable("serviceModelInfo", serviceModelInfo)
309 logger.debug(" ***** Completed prepareDecomposeService of create generic e2e service ***** ")
310 } catch (Exception ex) {
311 // try error in method block
312 String exceptionMessage = "Bpmn error encountered in create generic e2e service flow. Unexpected Error from method prepareDecomposeService() - " + ex.getMessage()
313 logger.error(exceptionMessage)
314 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, exceptionMessage)
318 private void generateRelatedResourceInfo(String response, JSONObject jObj){
320 def xml = new XmlSlurper().parseText(response)
321 def rtn = xml.childNodes()
322 while (rtn.hasNext()) {
323 groovy.util.slurpersupport.Node node = rtn.next()
324 def key = node.name()
325 def value = node.text()
330 private JSONObject getRelatedResourceInAAI (DelegateExecution execution, JSONObject jObj)
332 logger.debug(" ***** Started getRelatedResourceInAAI *****")
334 String aai_endpoint = UrnPropertiesReader.getVariable("aai.endpoint", execution)
335 String urlLink = jObj.get("resourceLinkUrl")
336 String serviceAaiPath = "${aai_endpoint}${urlLink}"
338 URL url = new URL(serviceAaiPath)
339 HttpClient client = new HttpClientFactory().newXmlClient(url, TargetEntity.AAI)
342 Response response = client.get()
343 int responseCode = response.getStatus()
344 execution.setVariable(Prefix + "GeRelatedResourceResponseCode", responseCode)
345 logger.debug(" Get RelatedResource code is: " + responseCode)
347 String aaiResponse = response.readEntity(String.class)
348 execution.setVariable(Prefix + "GetRelatedResourceResponse", aaiResponse)
351 if(responseCode == 200 || responseCode == 201 || responseCode == 202 )
352 //200 OK 201 CREATED 202 ACCEPTED
354 logger.debug("GET RelatedResource Received a Good Response")
355 execution.setVariable(Prefix + "SuccessIndicator", true)
356 execution.setVariable(Prefix + "FoundIndicator", true)
358 generateRelatedResourceInfo(aaiResponse, jObj)
360 //get model-invariant-uuid and model-uuid
361 String modelInvariantId = ""
362 String modelUuid = ""
363 String modelCustomizationId = ""
364 if(jObj.has("model-invariant-id")) {
365 modelInvariantId = jObj.get("model-invariant-id")
366 modelUuid = jObj.get("model-version-id")
367 modelCustomizationId = jObj.get("model-customization-id")
370 jObj.put("modelInvariantId", modelInvariantId)
371 jObj.put("modelVersionId", modelUuid)
372 jObj.put("modelCustomizationId", modelCustomizationId)
375 String exceptionMessage = "Get RelatedResource Received a Bad Response Code. Response Code is: " + responseCode
376 logger.error(exceptionMessage)
377 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, exceptionMessage)
380 logger.debug(" ***** Exit getRelatedResourceInAAI *****")
384 public void postDecomposeService(DelegateExecution execution) {
385 logger.debug(" ***** Inside postDecomposeService() of delete generic e2e service flow ***** ")
387 ServiceDecomposition serviceDecomposition = execution.getVariable("serviceDecomposition")
389 // service model info
390 execution.setVariable("serviceModelInfo", serviceDecomposition.getModelInfo())
392 List<Resource> deleteResourceList = serviceDecomposition.getServiceResources()
393 String serviceRelationShip = execution.getVariable("serviceRelationShip")
394 def jsonSlurper = new JsonSlurper()
395 def jsonOutput = new JsonOutput()
397 List relationShipList = null
398 if (serviceRelationShip != null) {
399 relationShipList = jsonSlurper.parseText(serviceRelationShip)
402 List<Resource> deleteRealResourceList = new ArrayList<Resource>()
404 //Set the real resource instance id to the decomosed resource list
405 //reset the resource instance id , because in the decompose flow ,its a random one.
406 //match the resource-instance-name and the model name
407 if (relationShipList != null) {
408 relationShipList.each {
410 JSONObject obj = getRelatedResourceInAAI(execution, (JSONObject)it)
412 for (Resource resource : deleteResourceList) {
414 String modelName = resource.getModelInfo().getModelName()
416 String modelCustomizationUuid = resource.getModelInfo().getModelCustomizationUuid()
417 if (StringUtils.containsIgnoreCase(obj.get("resourceType"), modelName)) {
418 resource.setResourceId(obj.get("resourceInstanceId"))
419 deleteRealResourceList.add(resource)
421 else if (modelCustomizationUuid.equals(obj.get("modelCustomizationId"))) {
422 resource.setResourceId(obj.get("resourceInstanceId"))
423 resource.setResourceInstanceName(obj.get("resourceType"))
424 deleteRealResourceList.add(resource)
430 // only delete real existing resources
431 execution.setVariable("deleteResourceList", deleteRealResourceList)
433 boolean isDeleteResourceListValid = false
434 if(deleteRealResourceList.size() > 0) {
435 isDeleteResourceListValid = true
437 execution.setVariable("isDeleteResourceListValid", isDeleteResourceListValid)
439 logger.debug("delete resource list : " + deleteRealResourceList)
440 } catch (Exception ex) {
441 String exceptionMessage = "Bpmn error encountered in create generic e2e service flow. processDecomposition() - " + ex.getMessage()
442 logger.error(exceptionMessage)
443 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, exceptionMessage)
445 logger.debug( " ***** exit postDecomposeService() of delete generic e2e service flow ***** ")
448 public void preInitResourcesOperStatus(DelegateExecution execution){
449 logger.debug(" ======== STARTED preInitResourcesOperStatus Process ======== ")
451 String serviceId = execution.getVariable("serviceInstanceId")
452 String operationId = execution.getVariable("operationId")
453 String operationType = execution.getVariable("operationType")
454 String resourceTemplateUUIDs = ""
455 String result = "processing"
456 String progress = "0"
458 String operationContent = "Prepare service creation"
459 logger.debug("Generated new operation for Service Instance serviceId:" + serviceId + " operationId:" + operationId + " operationType:" + operationType)
460 serviceId = UriUtils.encode(serviceId,"UTF-8")
461 execution.setVariable("serviceInstanceId", serviceId)
462 execution.setVariable("operationId", operationId)
463 execution.setVariable("operationType", operationType)
464 List<Resource> deleteResourceList = execution.getVariable("deleteResourceList")
466 String serviceRelationShip = execution.getVariable("serviceRelationShip")
467 for(Resource resource : deleteResourceList){
468 resourceTemplateUUIDs = resourceTemplateUUIDs + resource.getModelInfo().getModelCustomizationUuid() + ":"
471 def dbAdapterEndpoint = UrnPropertiesReader.getVariable("mso.adapters.openecomp.db.endpoint", execution)
472 execution.setVariable("URN_mso_adapters_openecomp_db_endpoint", dbAdapterEndpoint)
475 """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
476 xmlns:ns="http://org.onap.so/requestsdb">
479 <ns:initResourceOperationStatus xmlns:ns="http://org.onap.so/requestsdb">
480 <serviceId>${MsoUtils.xmlEscape(serviceId)}</serviceId>
481 <operationId>${MsoUtils.xmlEscape(operationId)}</operationId>
482 <operationType>${MsoUtils.xmlEscape(operationType)}</operationType>
483 <resourceTemplateUUIDs>${MsoUtils.xmlEscape(resourceTemplateUUIDs)}</resourceTemplateUUIDs>
484 </ns:initResourceOperationStatus>
486 </soapenv:Envelope>"""
488 payload = utils.formatXml(payload)
489 execution.setVariable("CVFMI_initResOperStatusRequest", payload)
490 logger.debug("Outgoing initResourceOperationStatus: \n" + payload)
491 logger.debug("CreateVfModuleInfra Outgoing initResourceOperationStatus Request: " + payload)
494 logger.debug("Exception Occured Processing preInitResourcesOperStatus. Exception is:\n" + e)
495 execution.setVariable("CVFMI_ErrorResponse", "Error Occurred during preInitResourcesOperStatus Method:\n" + e.getMessage())
497 logger.debug("======== COMPLETED preInitResourcesOperStatus Process ======== ")
500 public void prepareUpdateServiceOperationStatus(DelegateExecution execution){
501 logger.debug(" ======== STARTED prepareUpdateServiceOperationStatus Process ======== ")
503 String serviceId = execution.getVariable("serviceInstanceId")
504 String operationId = execution.getVariable("operationId")
506 String result = execution.getVariable("result")
507 String progress = execution.getVariable("progress")
509 String operationContent = execution.getVariable("operationContent")
511 serviceId = UriUtils.encode(serviceId,"UTF-8")
513 def dbAdapterEndpoint = UrnPropertiesReader.getVariable("mso.adapters.openecomp.db.endpoint", execution)
514 execution.setVariable("CVFMI_dbAdapterEndpoint", dbAdapterEndpoint)
515 logger.debug("DB Adapter Endpoint is: " + dbAdapterEndpoint)
518 """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
519 xmlns:ns="http://org.onap.so/requestsdb">
522 <ns:updateServiceOperationStatus xmlns:ns="http://org.onap.so/requestsdb">
523 <serviceId>${MsoUtils.xmlEscape(serviceId)}</serviceId>
524 <operationId>${MsoUtils.xmlEscape(operationId)}</operationId>
525 <operationType>DELETE</operationType>
526 <userId>${MsoUtils.xmlEscape(userId)}</userId>
527 <result>${MsoUtils.xmlEscape(result)}</result>
528 <operationContent>${MsoUtils.xmlEscape(operationContent)}</operationContent>
529 <progress>${MsoUtils.xmlEscape(progress)}</progress>
530 <reason>${MsoUtils.xmlEscape(reason)}</reason>
531 </ns:updateServiceOperationStatus>
533 </soapenv:Envelope>"""
535 payload = utils.formatXml(payload)
536 execution.setVariable("CVFMI_updateServiceOperStatusRequest", payload)
537 logger.debug("Outgoing updateServiceOperStatusRequest: \n" + payload)
540 logger.error("Exception Occured Processing prepareUpdateServiceOperationStatus. Exception is:\n" + e)
541 execution.setVariable("CVFMI_ErrorResponse", "Error Occurred during prepareUpdateServiceOperationStatus Method:\n" + e.getMessage())
543 logger.debug("======== COMPLETED prepareUpdateServiceOperationStatus Process ======== ")
547 * post config request.
549 public void postConfigRequest(execution){