3 * ============LICENSE_START=======================================================
5 * ================================================================================
6 * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
7 * ================================================================================
8 * Modifications Copyright (c) 2019 Samsung
9 * ================================================================================
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
21 * ============LICENSE_END=========================================================
23 package org.onap.so.bpmn.infrastructure.scripts
25 import org.apache.commons.lang3.tuple.ImmutablePair
26 import org.onap.so.bpmn.common.resource.ResourceRequestBuilder
27 import org.onap.so.bpmn.common.scripts.CatalogDbUtilsFactory
28 import org.onap.so.bpmn.core.domain.GroupResource
29 import org.onap.so.bpmn.core.domain.ModelInfo
30 import org.onap.so.bpmn.core.domain.ResourceType
32 import static org.apache.commons.lang3.StringUtils.isBlank
34 import org.apache.commons.lang3.StringUtils
35 import org.apache.http.HttpResponse
36 import org.camunda.bpm.engine.delegate.BpmnError
37 import org.camunda.bpm.engine.delegate.DelegateExecution
38 import org.json.JSONObject
39 import org.onap.so.bpmn.common.recipe.BpmnRestClient
40 import org.onap.so.bpmn.common.recipe.ResourceInput
41 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor
42 import org.onap.so.bpmn.common.scripts.CatalogDbUtils
43 import org.onap.so.bpmn.common.scripts.ExceptionUtil
44 import org.onap.so.bpmn.common.scripts.MsoUtils
45 import org.onap.so.bpmn.core.domain.AllottedResource
46 import org.onap.so.bpmn.core.domain.NetworkResource
47 import org.onap.so.bpmn.core.domain.Resource
48 import org.onap.so.bpmn.core.domain.ServiceDecomposition
49 import org.onap.so.bpmn.core.domain.VnfResource
50 import org.onap.so.bpmn.core.json.JsonUtils
51 import org.onap.so.bpmn.core.UrnPropertiesReader
52 import org.onap.so.bpmn.infrastructure.properties.BPMNProperties
53 import org.slf4j.Logger
54 import org.slf4j.LoggerFactory
63 * URN_mso_workflow_sdncadapter_callback
72 public class DoDeleteResourcesV1 extends AbstractServiceTaskProcessor {
73 private static final Logger logger = LoggerFactory.getLogger( DoDeleteResourcesV1.class);
76 ExceptionUtil exceptionUtil = new ExceptionUtil()
77 JsonUtils jsonUtil = new JsonUtils()
78 CatalogDbUtils catalogDbUtils = new CatalogDbUtilsFactory().create()
80 public void preProcessRequest (DelegateExecution execution) {
81 logger.debug(" ***** preProcessRequest *****")
85 String requestId = execution.getVariable("msoRequestId")
86 execution.setVariable("prefix",Prefix)
89 //requestDetails.subscriberInfo. for AAI GET & PUT & SDNC assignToplology
90 String globalSubscriberId = execution.getVariable("globalSubscriberId") //globalCustomerId
91 if (globalSubscriberId == null) {
92 execution.setVariable("globalSubscriberId", "")
95 //requestDetails.requestParameters. for AAI PUT & SDNC assignTopology
96 String serviceType = execution.getVariable("serviceType")
97 if (serviceType == null)
99 execution.setVariable("serviceType", "")
102 //Generated in parent for AAI PUT
103 String serviceInstanceId = execution.getVariable("serviceInstanceId")
104 if (isBlank(serviceInstanceId)){
105 msg = "Input serviceInstanceId is null"
107 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
110 String sdncCallbackUrl = UrnPropertiesReader.getVariable('mso.workflow.sdncadapter.callback', execution)
111 if (isBlank(sdncCallbackUrl)) {
112 msg = "URN_mso_workflow_sdncadapter_callback is null"
114 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
116 execution.setVariable("sdncCallbackUrl", sdncCallbackUrl)
117 logger.debug("SDNC Callback URL: " + sdncCallbackUrl)
119 StringBuilder sbParams = new StringBuilder()
120 Map<String, String> paramsMap = execution.getVariable("serviceInputParams")
121 if (paramsMap != null)
123 sbParams.append("<service-input-parameters>")
124 for (Map.Entry<String, String> entry : paramsMap.entrySet()) {
126 String paramName = entry.getKey()
127 String paramValue = entry.getValue()
130 <name>${MsoUtils.xmlEscape(paramName)}</name>
131 <value>${MsoUtils.xmlEscape(paramValue)}</value>
134 sbParams.append(paramsXml)
136 sbParams.append("</service-input-parameters>")
138 String siParamsXml = sbParams.toString()
139 if (siParamsXml == null)
141 execution.setVariable("siParamsXml", siParamsXml)
143 } catch (BpmnError e) {
145 } catch (Exception ex){
146 msg = "Exception in preProcessRequest " + ex.getMessage()
148 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
150 logger.debug(" ***** Exit preProcessRequest *****",)
153 public void sequenceResource(DelegateExecution execution){
154 logger.debug(" ======== STARTED sequenceResource Process ======== ")
155 List<Resource> sequencedResourceList = new ArrayList<Resource>()
156 List<Resource> wanResources = new ArrayList<Resource>()
158 // get delete resource list and order list
159 List<ImmutablePair<Resource, List<Resource>>> delResourceList = execution.getVariable("deleteResourceList")
161 ServiceDecomposition serviceDecomposition = execution.getVariable("serviceDecomposition")
162 String serviceModelName = serviceDecomposition.getModelInfo().getModelName();
163 String serviceModelUuid = serviceDecomposition.getModelInfo().getModelUuid();
165 Map<String, Map<String, Object>> parentVNF = new HashMap<>()
167 // get Sequence from properties
168 def resourceSequence = BPMNProperties.getResourceSequenceProp(serviceModelName)
170 // get Sequence from catalog db csar(model)
171 if(resourceSequence == null) {
172 resourceSequence = ResourceRequestBuilder.getResourceSequence(serviceModelUuid)
173 logger.info("Get Sequence from catalog db csar : " + resourceSequence)
176 if(resourceSequence != null) {
177 for (resourceType in resourceSequence.reverse()) {
179 boolean vfFound = false
181 for (ImmutablePair resourceTuple : delResourceList) {
182 Resource resource = resourceTuple.getKey()
183 List<Resource> groupResources = resourceTuple.getValue()
185 if (StringUtils.containsIgnoreCase(resource.getModelInfo().getModelName(), resourceType)) {
189 // if resource type is vnfResource then check for groups also
190 // Did not use continue because if same model type is used twice
191 // then we would like to add it twice for processing
192 // e.g. S{ V1{G1, G2, G1}} --> S{ {G2, G1, G1}V1}
193 // we will add in reverse order for deletion
194 if (resource instanceof VnfResource) {
195 if (resource.getGroupOrder() != null && !StringUtils.isEmpty(resource.getGroupOrder())) {
196 String[] grpSequence = resource.getGroupOrder().split(",")
198 Map<String, Object> parentVNFData = new HashMap<>()
199 parentVNFData.put("vfModelInfo", resource.getModelInfo())
200 parentVNFData.put("vnf-id", resource.getResourceId())
202 for (String grpType in grpSequence.reverse()) {
203 for (GroupResource gResource in groupResources) {
204 if (StringUtils.containsIgnoreCase(gResource.getModelInfo().getModelName(), grpType)) {
205 sequencedResourceList.add(gResource)
206 // Store parent VNF info for the group resource id
207 parentVNF.put(gResource.getResourceId(), parentVNFData)
214 sequencedResourceList.add(resource)
216 if (resource instanceof NetworkResource) {
217 wanResources.add(resource)
223 //define sequenced resource list, we deploy vf first and then network and then ar
224 //this is defaule sequence
225 // While deleting we will delete in resource order group resource, ar, network, then VF.
226 List<VnfResource> vnfResourceList = new ArrayList<VnfResource>()
227 List<AllottedResource> arResourceList = new ArrayList<AllottedResource>()
228 for (ImmutablePair resourceTuple : delResourceList) {
229 Resource rc = resourceTuple.getKey()
230 List<Resource> groupResources = resourceTuple.getValue()
232 if (rc instanceof VnfResource) {
233 vnfResourceList.add(rc)
234 if (rc.getGroupOrder() != null && !StringUtils.isEmpty(rc.getGroupOrder())) {
235 String[] grpSequence = rc.getGroupOrder().split(",")
237 Map<String, Object> parentVNFData = new HashMap<>()
238 parentVNFData.put("vfModelInfo", rc.getModelInfo())
239 parentVNFData.put("vnf-id", rc.getResourceId())
241 for (String grpType in grpSequence.reverse()) {
242 for (GroupResource gResource in groupResources) {
243 if (StringUtils.containsIgnoreCase(gResource.getModelInfo().getModelName(), grpType)) {
244 sequencedResourceList.add(gResource)
245 // Store parent VNF info for the group resource id
246 parentVNF.put(gResource.getResourceId(), parentVNFData)
251 } else if (rc instanceof NetworkResource) {
253 } else if (rc instanceof AllottedResource) {
254 arResourceList.add(rc)
258 sequencedResourceList.addAll(arResourceList)
259 sequencedResourceList.addAll(wanResources)
260 sequencedResourceList.addAll(vnfResourceList)
263 String isContainsWanResource = wanResources.isEmpty() ? "false" : "true"
264 //if no networkResource, get SDNC config from properties file
265 if( "false".equals(isContainsWanResource)) {
266 String serviceNeedSDNC = "mso.workflow.custom." + serviceModelName + ".sdnc.need";
267 isContainsWanResource = BPMNProperties.getProperty(serviceNeedSDNC, isContainsWanResource)
269 execution.setVariable("isContainsWanResource", isContainsWanResource)
270 execution.setVariable("currentResourceIndex", 0)
271 execution.setVariable("sequencedResourceList", sequencedResourceList)
272 execution.setVariable("parentVNF", parentVNF)
273 logger.debug("resourceSequence: " + resourceSequence)
274 logger.debug("delete resource sequence list : " + sequencedResourceList)
275 logger.debug(" ======== END sequenceResource Process ======== ")
279 * prepare delete parameters
281 public void preResourceDelete(DelegateExecution execution){
282 logger.debug(" ======== STARTED preResourceDelete Process ======== ")
284 List<Resource> sequencedResourceList = execution.getVariable("sequencedResourceList")
286 int currentIndex = execution.getVariable("currentResourceIndex")
287 if(sequencedResourceList != null && sequencedResourceList.size() > currentIndex){
288 Resource curResource = sequencedResourceList.get(currentIndex);
290 String resourceInstanceUUID = curResource.getResourceId()
291 String resourceTemplateUUID = curResource.getModelInfo().getModelUuid()
292 execution.setVariable("resourceInstanceId", resourceInstanceUUID)
293 execution.setVariable("currentResource", curResource)
294 logger.debug("Delete Resource Info resourceTemplate Id :" + resourceTemplateUUID + " resourceInstanceId: "
295 + resourceInstanceUUID + " resourceModelName: " + curResource.getModelInfo().getModelName())
298 execution.setVariable("resourceInstanceId", "")
301 logger.debug(" ======== END preResourceDelete Process ======== ")
306 * Execute delete workflow for resource
308 public void executeResourceDelete(DelegateExecution execution) {
309 logger.debug("======== Start executeResourceDelete Process ======== ")
311 String requestId = execution.getVariable("msoRequestId")
312 String serviceInstanceId = execution.getVariable("serviceInstanceId")
313 String serviceType = execution.getVariable("serviceType")
315 String resourceInstanceId = execution.getVariable("resourceInstanceId")
317 Resource currentResource = execution.getVariable("currentResource")
318 String action = "deleteInstance"
319 JSONObject resourceRecipe = catalogDbUtils.getResourceRecipe(execution, currentResource.getModelInfo().getModelUuid(), action)
320 String recipeUri = resourceRecipe.getString("orchestrationUri")
321 int recipeTimeout = resourceRecipe.getInt("recipeTimeout")
322 String recipeParamXsd = resourceRecipe.get("paramXSD")
325 ResourceInput resourceInput = new ResourceInput();
326 resourceInput.setServiceInstanceId(serviceInstanceId)
327 resourceInput.setResourceInstanceName(currentResource.getResourceInstanceName())
328 resourceInput.setResourceInstancenUuid(currentResource.getResourceId())
329 resourceInput.setOperationId(execution.getVariable("operationId"))
330 resourceInput.setOperationType(execution.getVariable("operationType"))
331 String globalSubscriberId = execution.getVariable("globalSubscriberId")
332 resourceInput.setGlobalSubscriberId(globalSubscriberId)
333 resourceInput.setResourceModelInfo(currentResource.getModelInfo());
334 ServiceDecomposition serviceDecomposition = execution.getVariable("serviceDecomposition")
335 resourceInput.setServiceModelInfo(serviceDecomposition.getModelInfo());
336 resourceInput.setServiceType(serviceType)
337 resourceInput.getResourceModelInfo().setModelType(currentResource.getResourceType().toString())
338 if (currentResource.getResourceType() == ResourceType.GROUP) {
339 Map<String, Map<String, Object>> parentVNF = execution.getVariable("parentVNF")
340 if((null != parentVNF) && (null!=parentVNF.get(currentResource.getResourceId()))){
341 Map<String, Object> parentVNFData = parentVNF.get(currentResource.getResourceId())
342 ModelInfo parentVNFModel = parentVNFData.get("vfModelInfo")
343 String parentResourceId = parentVNFData.get("vnf-id")
344 resourceInput.setVfModelInfo(parentVNFModel)
345 resourceInput.setVnfId(parentResourceId)
349 String recipeURL = BPMNProperties.getProperty("bpelURL", "http://so-bpmn-infra.onap:8081") + recipeUri
351 BpmnRestClient bpmnRestClient = new BpmnRestClient()
353 HttpResponse resp = bpmnRestClient.post(recipeURL, requestId, recipeTimeout, action, serviceInstanceId, serviceType, resourceInput.toString(), recipeParamXsd)
354 logger.debug(" ======== END executeResourceDelete Process ======== ")
355 } catch (BpmnError b) {
356 logger.error("Rethrowing MSOWorkflowException")
358 } catch (Exception e) {
359 logger.error("Error occured within DoDeleteResourcesV1 executeResourceDelete method: " + e)
360 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Internal Error - Occured during DoDeleteResourcesV1 executeResourceDelete Catalog")
365 public void parseNextResource(DelegateExecution execution){
366 logger.debug("======== Start parseNextResource Process ======== ")
367 def currentIndex = execution.getVariable("currentResourceIndex")
368 def nextIndex = currentIndex + 1
369 execution.setVariable("currentResourceIndex", nextIndex)
370 List<String> sequencedResourceList = execution.getVariable("sequencedResourceList")
371 if(nextIndex >= sequencedResourceList.size()){
372 execution.setVariable("allResourceFinished", "true")
374 execution.setVariable("allResourceFinished", "false")
376 logger.debug("======== COMPLETED parseNextResource Process ======== ")
379 public void prepareFinishedProgressForResource(DelegateExecution execution) {
381 String serviceInstanceId = execution.getVariable("serviceInstanceId")
382 String serviceType = execution.getVariable("serviceType")
383 String resourceInstanceId = execution.getVariable("resourceInstanceId")
384 Resource currentResource = execution.getVariable("currentResource")
385 String resourceCustomizationUuid = currentResource.getModelInfo().getModelCustomizationUuid()
386 String resourceModelName = currentResource.getModelInfo().getModelName()
387 String operationType = execution.getVariable("operationType")
388 String progress = "100"
389 String status = "finished"
390 String statusDescription = "The resource instance does not exist for " + resourceModelName
391 String operationId = execution.getVariable("operationId")
394 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
395 xmlns:ns="http://org.onap.so/requestsdb">
398 <ns:updateResourceOperationStatus>
399 <operType>${MsoUtils.xmlEscape(operationType)}</operType>
400 <operationId>${MsoUtils.xmlEscape(operationId)}</operationId>
401 <progress>${MsoUtils.xmlEscape(progress)}</progress>
402 <resourceTemplateUUID>${MsoUtils.xmlEscape(resourceCustomizationUuid)}</resourceTemplateUUID>
403 <serviceId>${MsoUtils.xmlEscape(serviceInstanceId)}</serviceId>
404 <status>${MsoUtils.xmlEscape(status)}</status>
405 <statusDescription>${MsoUtils.xmlEscape(statusDescription)}</statusDescription>
406 </ns:updateResourceOperationStatus>
408 </soapenv:Envelope>""";
410 def dbAdapterEndpoint = UrnPropertiesReader.getVariable("mso.adapters.openecomp.db.endpoint", execution)
411 execution.setVariable("CVFMI_dbAdapterEndpoint", dbAdapterEndpoint)
412 execution.setVariable("CVFMI_updateResOperStatusRequest", body)
415 public void prepareSDNCServiceDeactivateRequest (DelegateExecution execution) {
416 prepareSDNCServiceRequest (execution, "deactivate")
419 public void prepareSDNCServiceDeleteRequest (DelegateExecution execution) {
420 prepareSDNCServiceRequest (execution, "delete")
423 public void prepareSDNCServiceRequest (DelegateExecution execution, String svcAction) {
424 logger.debug(" ***** Started prepareSDNCServiceRequest for " + svcAction + "*****")
428 String sdnc_svcAction = svcAction
429 String sdncCallback = execution.getVariable("URN_mso_workflow_sdncadapter_callback")
430 String hdrRequestId = execution.getVariable("msoRequestId")
431 String serviceInstanceId = execution.getVariable("serviceInstanceId")
432 String source = execution.getVariable("source")
433 String sdnc_service_id = serviceInstanceId
434 ServiceDecomposition serviceDecomposition = execution.getVariable("serviceDecomposition")
435 String serviceType = execution.getVariable("serviceType")
436 String globalCustomerId = execution.getVariable("globalSubscriberId")
437 String serviceModelInvariantUuid = serviceDecomposition.getModelInfo().getModelInvariantUuid()
438 String serviceModelUuid = serviceDecomposition.getModelInfo().getModelUuid()
439 String serviceModelVersion = serviceDecomposition.getModelInfo().getModelVersion()
440 String serviceModelName = serviceDecomposition.getModelInfo().getModelName()
442 // 1. prepare assign topology via SDNC Adapter SUBFLOW call
443 String sndcTopologyDeleteRequest =
444 """<aetgt:SDNCAdapterWorkflowRequest xmlns:aetgt="http://org.onap/so/workflow/schema/v1"
445 xmlns:sdncadapter="http://org.onap.so/workflow/sdnc/adapter/schema/v1"
446 xmlns:sdncadapterworkflow="http://org.onap/so/workflow/schema/v1">
447 <sdncadapter:RequestHeader>
448 <sdncadapter:RequestId>${MsoUtils.xmlEscape(hdrRequestId)}</sdncadapter:RequestId>
449 <sdncadapter:SvcInstanceId>${MsoUtils.xmlEscape(serviceInstanceId)}</sdncadapter:SvcInstanceId>
450 <sdncadapter:SvcAction>${MsoUtils.xmlEscape(sdnc_svcAction)}</sdncadapter:SvcAction>
451 <sdncadapter:SvcOperation>service-topology-operation</sdncadapter:SvcOperation>
452 <sdncadapter:CallbackUrl>sdncCallback</sdncadapter:CallbackUrl>
453 <sdncadapter:MsoAction>generic-resource</sdncadapter:MsoAction>
454 </sdncadapter:RequestHeader>
455 <sdncadapterworkflow:SDNCRequestData>
456 <request-information>
457 <request-id>${MsoUtils.xmlEscape(hdrRequestId)}</request-id>
458 <request-action>DeleteServiceInstance</request-action>
459 <source>${MsoUtils.xmlEscape(source)}</source>
460 <notification-url></notification-url>
461 <order-number></order-number>
462 <order-version></order-version>
463 </request-information>
464 <service-information>
465 <service-id>${MsoUtils.xmlEscape(serviceInstanceId)}</service-id>
466 <subscription-service-type>${MsoUtils.xmlEscape(serviceType)}</subscription-service-type>
467 <onap-model-information>
468 <model-invariant-uuid>${MsoUtils.xmlEscape(serviceModelInvariantUuid)}</model-invariant-uuid>
469 <model-uuid>${MsoUtils.xmlEscape(serviceModelUuid)}</model-uuid>
470 <model-version>${MsoUtils.xmlEscape(serviceModelVersion)}</model-version>
471 <model-name>${MsoUtils.xmlEscape(serviceModelName)}</model-name>
472 </onap-model-information>
473 <service-instance-id>${MsoUtils.xmlEscape(serviceInstanceId)}</service-instance-id>
474 <global-customer-id>${MsoUtils.xmlEscape(globalCustomerId)}</global-customer-id>
475 </service-information>
476 <service-request-input>
477 </service-request-input>
478 </sdncadapterworkflow:SDNCRequestData>
479 </aetgt:SDNCAdapterWorkflowRequest>""".trim()
481 String sndcTopologyDeleteRequesAsString = utils.formatXml(sndcTopologyDeleteRequest)
482 logger.debug(sndcTopologyDeleteRequesAsString)
483 execution.setVariable("sdncAdapterWorkflowRequest", sndcTopologyDeleteRequesAsString)
484 logger.debug("sdncAdapterWorkflowRequest - " + "\n" + sndcTopologyDeleteRequesAsString)
486 } catch (Exception ex) {
487 String exceptionMessage = " Bpmn error encountered in DoDeleteResourcesV1 flow. prepareSDNCServiceRequest() - " + ex.getMessage()
488 logger.debug(exceptionMessage)
489 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, exceptionMessage)
492 logger.debug("***** Exit prepareSDNCServiceRequest for " + svcAction + "*****")