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.domain.Resource
40 import org.onap.so.bpmn.core.domain.ServiceDecomposition
41 import org.onap.so.bpmn.core.json.JsonUtils
42 import org.onap.so.client.HttpClient
43 import org.onap.so.client.HttpClientFactory
44 import org.onap.so.client.aai.AAIObjectType
45 import org.onap.so.client.aai.AAIResourcesClient
46 import org.onap.so.client.aai.entities.AAIResultWrapper
47 import org.onap.so.client.aai.entities.uri.AAIResourceUri
48 import org.onap.so.client.aai.entities.uri.AAIUriFactory
49 import org.slf4j.Logger
50 import org.slf4j.LoggerFactory
51 import org.onap.so.utils.TargetEntity
52 import org.springframework.web.util.UriUtils
54 import javax.ws.rs.NotFoundException
55 import javax.ws.rs.core.Response
58 import static org.apache.commons.lang3.StringUtils.isBlank
61 * This groovy class supports the <class>DoDeleteE2EServiceInstance.bpmn</class> process.
64 * @param - msoRequestId
65 * @param - globalSubscriberId - O
66 * @param - subscriptionServiceType - O
67 * @param - serviceInstanceId
68 * @param - serviceInstanceName - O
69 * @param - serviceInputParams (should contain aic_zone for serviceTypes TRANSPORT,ATM)
70 * @param - sdncVersion
71 * @param - failNotFound - TODO
72 * @param - serviceInputParams - TODO
74 * @param - delResourceList
75 * @param - serviceRelationShip
78 * @param - WorkflowException
82 public class DoDeleteE2EServiceInstance extends AbstractServiceTaskProcessor {
84 String Prefix="DDEESI_"
85 ExceptionUtil exceptionUtil = new ExceptionUtil()
86 JsonUtils jsonUtil = new JsonUtils()
87 private static final Logger logger = LoggerFactory.getLogger( DoDeleteE2EServiceInstance.class);
90 public void preProcessRequest (DelegateExecution execution) {
91 logger.debug(" ***** preProcessRequest *****")
95 String requestId = execution.getVariable("msoRequestId")
96 execution.setVariable("prefix",Prefix)
99 //requestDetails.subscriberInfo. for AAI GET & PUT & SDNC assignToplology
100 String globalSubscriberId = execution.getVariable("globalSubscriberId") //globalCustomerId
101 if (globalSubscriberId == null)
103 execution.setVariable("globalSubscriberId", "")
106 //requestDetails.requestParameters. for AAI PUT & SDNC assignTopology
107 String serviceType = execution.getVariable("serviceType")
108 if (serviceType == null)
110 execution.setVariable("serviceType", "")
113 //Generated in parent for AAI PUT
114 String serviceInstanceId = execution.getVariable("serviceInstanceId")
115 if (isBlank(serviceInstanceId)){
116 msg = "Input serviceInstanceId is null"
118 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
121 String sdncCallbackUrl = UrnPropertiesReader.getVariable('mso.workflow.sdncadapter.callback', execution)
122 if (isBlank(sdncCallbackUrl)) {
123 msg = "URN_mso_workflow_sdncadapter_callback is null"
125 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
127 execution.setVariable("sdncCallbackUrl", sdncCallbackUrl)
128 logger.info("SDNC Callback URL: " + sdncCallbackUrl)
130 StringBuilder sbParams = new StringBuilder()
131 Map<String, String> paramsMap = execution.getVariable("serviceInputParams")
133 if (paramsMap != null) {
134 sbParams.append("<service-input-parameters>")
135 for (Map.Entry<String, String> entry : paramsMap.entrySet()) {
137 String paramName = entry.getKey()
138 String paramValue = entry.getValue()
141 <name>${MsoUtils.xmlEscape(paramName)}</name>
142 <value>${MsoUtils.xmlEscape(paramValue)}</value>
145 sbParams.append(paramsXml)
147 sbParams.append("</service-input-parameters>")
149 String siParamsXml = sbParams.toString()
150 if (siParamsXml == null)
152 execution.setVariable("siParamsXml", siParamsXml)
154 } catch (BpmnError e) {
156 } catch (Exception ex){
157 msg = "Exception in preProcessRequest " + ex.getMessage()
159 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
161 logger.debug("***** Exit preProcessRequest *****")
164 public void postProcessAAIGET(DelegateExecution execution) {
165 logger.debug(" ***** postProcessAAIGET ***** ")
169 String serviceInstanceId = execution.getVariable('serviceInstanceId')
170 String globalSubscriberId = execution.getVariable('globalSubscriberId')
171 String serviceType = execution.getVariable('serviceType')
172 AAIResourcesClient resourceClient = new AAIResourcesClient()
173 AAIResourceUri serviceInstanceUri = AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE, globalSubscriberId, serviceType, serviceInstanceId)
174 if (!resourceClient.exists(serviceInstanceUri)) {
175 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Service Instance was not found in aai")
177 AAIResultWrapper wrapper = resourceClient.get(serviceInstanceUri, NotFoundException.class)
178 Optional<ServiceInstance> si = wrapper.asBean(ServiceInstance.class)
180 if (si.isPresent() && StringUtils.isNotEmpty(si.get().getServiceInstanceName())) {
181 logger.debug("Found Service-instance in AAI")
182 execution.setVariable("serviceInstanceName", si.get().getServiceInstanceName())
183 // get model invariant id
184 // Get Template uuid and version
185 if ((null != si.get().getModelInvariantId()) && (null != si.get().getModelVersionId())) {
186 logger.debug("SI Data model-invariant-id and model-version-id exist")
187 // Set Original Template info
188 execution.setVariable("model-invariant-id-original", si.get().getModelInvariantId())
189 execution.setVariable("model-version-id-original", si.get().getModelVersionId())
191 if ((null != si.get().getRelationshipList()) && (null != si.get().getRelationshipList().getRelationship())) {
192 logger.debug("SI Data relationship-list exists")
193 List<Relationship> relationshipList = si.get().getRelationshipList().getRelationship()
194 JSONArray jArray = new JSONArray()
195 for (Relationship relationship : relationshipList) {
196 def jObj = getRelationShipData(relationship)
199 execution.setVariable("serviceRelationShip", jArray.toString())
202 msg = "Service-instance: " + serviceInstanceId + " NOT found in AAI."
204 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, msg)
206 } catch (BpmnError e) {
208 } catch (NotFoundException e) {
209 logger.debug("Service Instance does not exist AAI")
210 exceptionUtil.buildAndThrowWorkflowException(execution, 404, "Service Instance was not found in aai")
211 } catch (Exception ex) {
212 msg = "Exception in DoDeleteE2EServiceInstance.postProcessAAIGET. " + ex.getMessage()
214 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
216 logger.debug(" *** Exit postProcessAAIGET *** ")
219 private JSONObject getRelationShipData(Relationship relationship) {
220 JSONObject jObj = new JSONObject()
221 def rt = relationship.getRelatedTo()
222 def rl = relationship.getRelatedLink()
223 logger.debug("ServiceInstance Related NS/Configuration :" + rl)
224 List<RelationshipData> rl_datas = relationship.getRelationshipData()
225 for (RelationshipData rl_data : rl_datas) {
226 def eKey = rl_data.getRelationshipKey()
227 def eValue = rl_data.getRelationshipValue()
228 if ((rt.equals("service-instance") && eKey.equals("service-instance.service-instance-id"))
229 //for overlay/underlay
230 || (rt.equals("configuration") && eKey.equals("configuration.configuration-id")
232 jObj.put("resourceInstanceId", eValue)
234 // for sp-partner and others
235 else if (eKey.endsWith("-id")) {
236 jObj.put("resourceInstanceId", eValue)
237 String resourceName = rt + eValue;
238 jObj.put("resourceType", resourceName)
240 jObj.put("resourceLinkUrl", rl)
242 List<RelatedToProperty> rl_props = relationship.getRelatedToProperty()
243 for (RelatedToProperty rl_prop : rl_props) {
244 def eKey = rl_prop.getPropertyKey()
245 def eValue = rl_prop.getPropertyValue()
246 if ((rt.equals("service-instance") && eKey.equals("service-instance.service-instance-name"))
247 //for overlay/underlay
248 || (rt.equals("configuration") && eKey.equals("configuration.configuration-type"))) {
249 jObj.put("resourceType", eValue)
252 logger.debug("Relationship related to Resource:" + jObj.toString())
256 public void getCurrentNS(DelegateExecution execution){
257 logger.info( "======== Start getCurrentNS Process ======== ")
259 def currentIndex = execution.getVariable("currentNSIndex")
260 List<String> nsSequence = execution.getVariable("nsSequence")
261 String nsResourceType = nsSequence.get(currentIndex)
263 // GET AAI by Name, not ID, for process convenient
264 execution.setVariable("GENGS_type", "service-instance")
265 execution.setVariable("GENGS_serviceInstanceId", "")
266 execution.setVariable("GENGS_serviceInstanceName", nsResourceType)
268 logger.debug("======== COMPLETED getCurrentNS Process ======== ")
271 public void prepareDecomposeService(DelegateExecution execution) {
273 logger.debug(" ***** Inside prepareDecomposeService of create generic e2e service ***** ")
274 String modelInvariantUuid = execution.getVariable("model-invariant-id-original")
275 String modelVersionId = execution.getVariable("model-version-id-original")
277 String serviceModelInfo = """{
278 "modelInvariantUuid":"${modelInvariantUuid}",
279 "modelUuid":"${modelVersionId}",
282 execution.setVariable("serviceModelInfo", serviceModelInfo)
284 logger.debug(" ***** Completed prepareDecomposeService of create generic e2e service ***** ")
285 } catch (Exception ex) {
286 // try error in method block
287 String exceptionMessage = "Bpmn error encountered in create generic e2e service flow. Unexpected Error from method prepareDecomposeService() - " + ex.getMessage()
288 logger.error(exceptionMessage)
289 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, exceptionMessage)
293 private void generateRelatedResourceInfo(String response, JSONObject jObj){
295 def xml = new XmlSlurper().parseText(response)
296 def rtn = xml.childNodes()
297 while (rtn.hasNext()) {
298 groovy.util.slurpersupport.Node node = rtn.next()
299 def key = node.name()
300 def value = node.text()
305 private JSONObject getRelatedResourceInAAI (DelegateExecution execution, JSONObject jObj)
307 logger.debug(" ***** Started getRelatedResourceInAAI *****")
309 String aai_endpoint = UrnPropertiesReader.getVariable("aai.endpoint", execution)
310 String urlLink = jObj.get("resourceLinkUrl")
311 String serviceAaiPath = "${aai_endpoint}${urlLink}"
313 URL url = new URL(serviceAaiPath)
314 HttpClient client = new HttpClientFactory().newXmlClient(url, TargetEntity.AAI)
317 Response response = client.get()
318 int responseCode = response.getStatus()
319 execution.setVariable(Prefix + "GeRelatedResourceResponseCode", responseCode)
320 logger.debug(" Get RelatedResource code is: " + responseCode)
322 String aaiResponse = response.readEntity(String.class)
323 execution.setVariable(Prefix + "GetRelatedResourceResponse", aaiResponse)
326 if(responseCode == 200 || responseCode == 201 || responseCode == 202 )
327 //200 OK 201 CREATED 202 ACCEPTED
329 logger.debug("GET RelatedResource Received a Good Response")
330 execution.setVariable(Prefix + "SuccessIndicator", true)
331 execution.setVariable(Prefix + "FoundIndicator", true)
333 generateRelatedResourceInfo(aaiResponse, jObj)
335 //get model-invariant-uuid and model-uuid
336 String modelInvariantId = ""
337 String modelUuid = ""
338 String modelCustomizationId = ""
339 if(jObj.has("model-invariant-id")) {
340 modelInvariantId = jObj.get("model-invariant-id")
341 modelUuid = jObj.get("model-version-id")
342 modelCustomizationId = jObj.get("model-customization-id")
345 jObj.put("modelInvariantId", modelInvariantId)
346 jObj.put("modelVersionId", modelUuid)
347 jObj.put("modelCustomizationId", modelCustomizationId)
350 String exceptionMessage = "Get RelatedResource Received a Bad Response Code. Response Code is: " + responseCode
351 logger.error(exceptionMessage)
352 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, exceptionMessage)
355 logger.debug(" ***** Exit getRelatedResourceInAAI *****")
359 public void postDecomposeService(DelegateExecution execution) {
360 logger.debug(" ***** Inside postDecomposeService() of delete generic e2e service flow ***** ")
362 ServiceDecomposition serviceDecomposition = execution.getVariable("serviceDecomposition")
364 // service model info
365 execution.setVariable("serviceModelInfo", serviceDecomposition.getModelInfo())
367 List<Resource> deleteResourceList = serviceDecomposition.getServiceResources()
368 String serviceRelationShip = execution.getVariable("serviceRelationShip")
369 def jsonSlurper = new JsonSlurper()
370 def jsonOutput = new JsonOutput()
372 List relationShipList = null
373 if (serviceRelationShip != null) {
374 relationShipList = jsonSlurper.parseText(serviceRelationShip)
377 List<Resource> deleteRealResourceList = new ArrayList<Resource>()
379 //Set the real resource instance id to the decomosed resource list
380 //reset the resource instance id , because in the decompose flow ,its a random one.
381 //match the resource-instance-name and the model name
382 if (relationShipList != null) {
383 relationShipList.each {
385 JSONObject obj = getRelatedResourceInAAI(execution, (JSONObject)it)
387 for (Resource resource : deleteResourceList) {
389 String modelName = resource.getModelInfo().getModelName()
391 String modelCustomizationUuid = resource.getModelInfo().getModelCustomizationUuid()
392 if (StringUtils.containsIgnoreCase(obj.get("resourceType"), modelName)) {
393 resource.setResourceId(obj.get("resourceInstanceId"))
394 deleteRealResourceList.add(resource)
396 else if (modelCustomizationUuid.equals(obj.get("modelCustomizationId"))) {
397 resource.setResourceId(obj.get("resourceInstanceId"))
398 resource.setResourceInstanceName(obj.get("resourceType"))
399 deleteRealResourceList.add(resource)
405 // only delete real existing resources
406 execution.setVariable("deleteResourceList", deleteRealResourceList)
408 boolean isDeleteResourceListValid = false
409 if(deleteRealResourceList.size() > 0) {
410 isDeleteResourceListValid = true
412 execution.setVariable("isDeleteResourceListValid", isDeleteResourceListValid)
414 logger.debug("delete resource list : " + deleteRealResourceList)
415 } catch (Exception ex) {
416 String exceptionMessage = "Bpmn error encountered in create generic e2e service flow. processDecomposition() - " + ex.getMessage()
417 logger.error(exceptionMessage)
418 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, exceptionMessage)
420 logger.debug(" ***** exit postDecomposeService() of delete generic e2e service flow ***** ")
423 public void preInitResourcesOperStatus(DelegateExecution execution){
424 logger.debug(" ======== STARTED preInitResourcesOperStatus Process ======== ")
426 String serviceId = execution.getVariable("serviceInstanceId")
427 String operationId = execution.getVariable("operationId")
428 String operationType = execution.getVariable("operationType")
429 String resourceTemplateUUIDs = ""
430 String result = "processing"
431 String progress = "0"
433 String operationContent = "Prepare service creation"
434 logger.debug("Generated new operation for Service Instance serviceId:" + serviceId + " operationId:" + operationId + " operationType:" + operationType)
435 serviceId = UriUtils.encode(serviceId,"UTF-8")
436 execution.setVariable("serviceInstanceId", serviceId)
437 execution.setVariable("operationId", operationId)
438 execution.setVariable("operationType", operationType)
439 List<Resource> deleteResourceList = execution.getVariable("deleteResourceList")
441 String serviceRelationShip = execution.getVariable("serviceRelationShip")
442 for(Resource resource : deleteResourceList){
443 resourceTemplateUUIDs = resourceTemplateUUIDs + resource.getModelInfo().getModelCustomizationUuid() + ":"
446 def dbAdapterEndpoint = UrnPropertiesReader.getVariable("mso.adapters.openecomp.db.endpoint", execution)
447 execution.setVariable("URN_mso_adapters_openecomp_db_endpoint", dbAdapterEndpoint)
450 """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
451 xmlns:ns="http://org.onap.so/requestsdb">
454 <ns:initResourceOperationStatus xmlns:ns="http://org.onap.so/requestsdb">
455 <serviceId>${MsoUtils.xmlEscape(serviceId)}</serviceId>
456 <operationId>${MsoUtils.xmlEscape(operationId)}</operationId>
457 <operationType>${MsoUtils.xmlEscape(operationType)}</operationType>
458 <resourceTemplateUUIDs>${MsoUtils.xmlEscape(resourceTemplateUUIDs)}</resourceTemplateUUIDs>
459 </ns:initResourceOperationStatus>
461 </soapenv:Envelope>"""
463 payload = utils.formatXml(payload)
464 execution.setVariable("CVFMI_initResOperStatusRequest", payload)
465 logger.debug("Outgoing initResourceOperationStatus: \n" + payload)
466 logger.debug("CreateVfModuleInfra Outgoing initResourceOperationStatus Request: " + payload)
469 logger.debug("Exception Occured Processing preInitResourcesOperStatus. Exception is:\n" + e)
470 execution.setVariable("CVFMI_ErrorResponse", "Error Occurred during preInitResourcesOperStatus Method:\n" + e.getMessage())
472 logger.debug("======== COMPLETED preInitResourcesOperStatus Process ======== ")
475 public void prepareUpdateServiceOperationStatus(DelegateExecution execution){
476 logger.debug(" ======== STARTED prepareUpdateServiceOperationStatus Process ======== ")
478 String serviceId = execution.getVariable("serviceInstanceId")
479 String operationId = execution.getVariable("operationId")
481 String result = execution.getVariable("result")
482 String progress = execution.getVariable("progress")
484 String operationContent = execution.getVariable("operationContent")
486 serviceId = UriUtils.encode(serviceId,"UTF-8")
488 def dbAdapterEndpoint = UrnPropertiesReader.getVariable("mso.adapters.openecomp.db.endpoint", execution)
489 execution.setVariable("CVFMI_dbAdapterEndpoint", dbAdapterEndpoint)
490 logger.debug("DB Adapter Endpoint is: " + dbAdapterEndpoint)
493 """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
494 xmlns:ns="http://org.onap.so/requestsdb">
497 <ns:updateServiceOperationStatus xmlns:ns="http://org.onap.so/requestsdb">
498 <serviceId>${MsoUtils.xmlEscape(serviceId)}</serviceId>
499 <operationId>${MsoUtils.xmlEscape(operationId)}</operationId>
500 <operationType>DELETE</operationType>
501 <userId>${MsoUtils.xmlEscape(userId)}</userId>
502 <result>${MsoUtils.xmlEscape(result)}</result>
503 <operationContent>${MsoUtils.xmlEscape(operationContent)}</operationContent>
504 <progress>${MsoUtils.xmlEscape(progress)}</progress>
505 <reason>${MsoUtils.xmlEscape(reason)}</reason>
506 </ns:updateServiceOperationStatus>
508 </soapenv:Envelope>"""
510 payload = utils.formatXml(payload)
511 execution.setVariable("CVFMI_updateServiceOperStatusRequest", payload)
512 logger.debug("Outgoing updateServiceOperStatusRequest: \n" + payload)
515 logger.error("Exception Occured Processing prepareUpdateServiceOperationStatus. Exception is:\n" + e)
516 execution.setVariable("CVFMI_ErrorResponse", "Error Occurred during prepareUpdateServiceOperationStatus Method:\n" + e.getMessage())
518 logger.debug("======== COMPLETED prepareUpdateServiceOperationStatus Process ======== ")
522 * post config request.
524 public void postConfigRequest(execution){