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(" ======== END sequenceResource Process ======== ")
278 * prepare delete parameters
280 public void preResourceDelete(DelegateExecution execution){
281 logger.debug(" ======== STARTED preResourceDelete Process ======== ")
283 List<Resource> sequencedResourceList = execution.getVariable("sequencedResourceList")
285 int currentIndex = execution.getVariable("currentResourceIndex")
286 if(sequencedResourceList != null && sequencedResourceList.size() > currentIndex){
287 Resource curResource = sequencedResourceList.get(currentIndex);
289 String resourceInstanceUUID = curResource.getResourceId()
290 String resourceTemplateUUID = curResource.getModelInfo().getModelUuid()
291 execution.setVariable("resourceInstanceId", resourceInstanceUUID)
292 execution.setVariable("currentResource", curResource)
293 logger.debug("Delete Resource Info resourceTemplate Id :" + resourceTemplateUUID + " resourceInstanceId: "
294 + resourceInstanceUUID + " resourceModelName: " + curResource.getModelInfo().getModelName())
297 execution.setVariable("resourceInstanceId", "")
300 logger.debug(" ======== END preResourceDelete Process ======== ")
305 * Execute delete workflow for resource
307 public void executeResourceDelete(DelegateExecution execution) {
308 logger.debug("======== Start executeResourceDelete Process ======== ")
310 String requestId = execution.getVariable("msoRequestId")
311 String serviceInstanceId = execution.getVariable("serviceInstanceId")
312 String serviceType = execution.getVariable("serviceType")
314 String resourceInstanceId = execution.getVariable("resourceInstanceId")
316 Resource currentResource = execution.getVariable("currentResource")
317 String action = "deleteInstance"
318 JSONObject resourceRecipe = catalogDbUtils.getResourceRecipe(execution, currentResource.getModelInfo().getModelUuid(), action)
319 String recipeUri = resourceRecipe.getString("orchestrationUri")
320 int recipeTimeout = resourceRecipe.getInt("recipeTimeout")
321 String recipeParamXsd = resourceRecipe.get("paramXSD")
324 ResourceInput resourceInput = new ResourceInput();
325 resourceInput.setServiceInstanceId(serviceInstanceId)
326 resourceInput.setResourceInstanceName(currentResource.getResourceInstanceName())
327 resourceInput.setResourceInstancenUuid(currentResource.getResourceId())
328 resourceInput.setOperationId(execution.getVariable("operationId"))
329 resourceInput.setOperationType(execution.getVariable("operationType"))
330 String globalSubscriberId = execution.getVariable("globalSubscriberId")
331 resourceInput.setGlobalSubscriberId(globalSubscriberId)
332 resourceInput.setResourceModelInfo(currentResource.getModelInfo());
333 ServiceDecomposition serviceDecomposition = execution.getVariable("serviceDecomposition")
334 resourceInput.setServiceModelInfo(serviceDecomposition.getModelInfo());
335 resourceInput.setServiceType(serviceType)
336 resourceInput.getResourceModelInfo().setModelType(currentResource.getResourceType().toString())
337 if (currentResource.getResourceType() == ResourceType.GROUP) {
338 Map<String, Map<String, Object>> parentVNF = execution.getVariable("parentVNF")
339 if((null != parentVNF) && (null!=parentVNF.get(currentResource.getResourceId()))){
340 Map<String, Object> parentVNFData = parentVNF.get(currentResource.getResourceId())
341 ModelInfo parentVNFModel = parentVNFData.get("vfModelInfo")
342 String parentResourceId = parentVNFData.get("vnf-id")
343 resourceInput.setVfModelInfo(parentVNFModel)
344 resourceInput.setVnfId(parentResourceId)
348 String recipeURL = BPMNProperties.getProperty("bpelURL", "http://so-bpmn-infra.onap:8081") + recipeUri
350 BpmnRestClient bpmnRestClient = new BpmnRestClient()
352 HttpResponse resp = bpmnRestClient.post(recipeURL, requestId, recipeTimeout, action, serviceInstanceId, serviceType, resourceInput.toString(), recipeParamXsd)
353 logger.debug(" ======== END executeResourceDelete Process ======== ")
354 } catch (BpmnError b) {
355 logger.error("Rethrowing MSOWorkflowException")
357 } catch (Exception e) {
358 logger.error("Error occured within DoDeleteResourcesV1 executeResourceDelete method: " + e)
359 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Internal Error - Occured during DoDeleteResourcesV1 executeResourceDelete Catalog")
364 public void parseNextResource(DelegateExecution execution){
365 logger.debug("======== Start parseNextResource Process ======== ")
366 def currentIndex = execution.getVariable("currentResourceIndex")
367 def nextIndex = currentIndex + 1
368 execution.setVariable("currentResourceIndex", nextIndex)
369 List<String> sequencedResourceList = execution.getVariable("sequencedResourceList")
370 if(nextIndex >= sequencedResourceList.size()){
371 execution.setVariable("allResourceFinished", "true")
373 execution.setVariable("allResourceFinished", "false")
375 logger.debug("======== COMPLETED parseNextResource Process ======== ")
378 public void prepareFinishedProgressForResource(DelegateExecution execution) {
380 String serviceInstanceId = execution.getVariable("serviceInstanceId")
381 String serviceType = execution.getVariable("serviceType")
382 String resourceInstanceId = execution.getVariable("resourceInstanceId")
383 Resource currentResource = execution.getVariable("currentResource")
384 String resourceCustomizationUuid = currentResource.getModelInfo().getModelCustomizationUuid()
385 String resourceModelName = currentResource.getModelInfo().getModelName()
386 String operationType = execution.getVariable("operationType")
387 String progress = "100"
388 String status = "finished"
389 String statusDescription = "The resource instance does not exist for " + resourceModelName
390 String operationId = execution.getVariable("operationId")
393 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
394 xmlns:ns="http://org.onap.so/requestsdb">
397 <ns:updateResourceOperationStatus>
398 <operType>${MsoUtils.xmlEscape(operationType)}</operType>
399 <operationId>${MsoUtils.xmlEscape(operationId)}</operationId>
400 <progress>${MsoUtils.xmlEscape(progress)}</progress>
401 <resourceTemplateUUID>${MsoUtils.xmlEscape(resourceCustomizationUuid)}</resourceTemplateUUID>
402 <serviceId>${MsoUtils.xmlEscape(serviceInstanceId)}</serviceId>
403 <status>${MsoUtils.xmlEscape(status)}</status>
404 <statusDescription>${MsoUtils.xmlEscape(statusDescription)}</statusDescription>
405 </ns:updateResourceOperationStatus>
407 </soapenv:Envelope>""";
409 def dbAdapterEndpoint = UrnPropertiesReader.getVariable("mso.adapters.openecomp.db.endpoint", execution)
410 execution.setVariable("CVFMI_dbAdapterEndpoint", dbAdapterEndpoint)
411 execution.setVariable("CVFMI_updateResOperStatusRequest", body)
414 public void prepareSDNCServiceDeactivateRequest (DelegateExecution execution) {
415 prepareSDNCServiceRequest (execution, "deactivate")
418 public void prepareSDNCServiceDeleteRequest (DelegateExecution execution) {
419 prepareSDNCServiceRequest (execution, "delete")
422 public void prepareSDNCServiceRequest (DelegateExecution execution, String svcAction) {
423 logger.debug(" ***** Started prepareSDNCServiceRequest for " + svcAction + "*****")
427 String sdnc_svcAction = svcAction
428 String sdncCallback = execution.getVariable("URN_mso_workflow_sdncadapter_callback")
429 String hdrRequestId = execution.getVariable("msoRequestId")
430 String serviceInstanceId = execution.getVariable("serviceInstanceId")
431 String source = execution.getVariable("source")
432 String sdnc_service_id = serviceInstanceId
433 ServiceDecomposition serviceDecomposition = execution.getVariable("serviceDecomposition")
434 String serviceType = execution.getVariable("serviceType")
435 String globalCustomerId = execution.getVariable("globalSubscriberId")
436 String serviceModelInvariantUuid = serviceDecomposition.getModelInfo().getModelInvariantUuid()
437 String serviceModelUuid = serviceDecomposition.getModelInfo().getModelUuid()
438 String serviceModelVersion = serviceDecomposition.getModelInfo().getModelVersion()
439 String serviceModelName = serviceDecomposition.getModelInfo().getModelName()
441 // 1. prepare assign topology via SDNC Adapter SUBFLOW call
442 String sndcTopologyDeleteRequest =
443 """<aetgt:SDNCAdapterWorkflowRequest xmlns:aetgt="http://org.onap/so/workflow/schema/v1"
444 xmlns:sdncadapter="http://org.onap.so/workflow/sdnc/adapter/schema/v1"
445 xmlns:sdncadapterworkflow="http://org.onap/so/workflow/schema/v1">
446 <sdncadapter:RequestHeader>
447 <sdncadapter:RequestId>${MsoUtils.xmlEscape(hdrRequestId)}</sdncadapter:RequestId>
448 <sdncadapter:SvcInstanceId>${MsoUtils.xmlEscape(serviceInstanceId)}</sdncadapter:SvcInstanceId>
449 <sdncadapter:SvcAction>${MsoUtils.xmlEscape(sdnc_svcAction)}</sdncadapter:SvcAction>
450 <sdncadapter:SvcOperation>service-topology-operation</sdncadapter:SvcOperation>
451 <sdncadapter:CallbackUrl>sdncCallback</sdncadapter:CallbackUrl>
452 <sdncadapter:MsoAction>generic-resource</sdncadapter:MsoAction>
453 </sdncadapter:RequestHeader>
454 <sdncadapterworkflow:SDNCRequestData>
455 <request-information>
456 <request-id>${MsoUtils.xmlEscape(hdrRequestId)}</request-id>
457 <request-action>DeleteServiceInstance</request-action>
458 <source>${MsoUtils.xmlEscape(source)}</source>
459 <notification-url></notification-url>
460 <order-number></order-number>
461 <order-version></order-version>
462 </request-information>
463 <service-information>
464 <service-id>${MsoUtils.xmlEscape(serviceInstanceId)}</service-id>
465 <subscription-service-type>${MsoUtils.xmlEscape(serviceType)}</subscription-service-type>
466 <onap-model-information>
467 <model-invariant-uuid>${MsoUtils.xmlEscape(serviceModelInvariantUuid)}</model-invariant-uuid>
468 <model-uuid>${MsoUtils.xmlEscape(serviceModelUuid)}</model-uuid>
469 <model-version>${MsoUtils.xmlEscape(serviceModelVersion)}</model-version>
470 <model-name>${MsoUtils.xmlEscape(serviceModelName)}</model-name>
471 </onap-model-information>
472 <service-instance-id>${MsoUtils.xmlEscape(serviceInstanceId)}</service-instance-id>
473 <global-customer-id>${MsoUtils.xmlEscape(globalCustomerId)}</global-customer-id>
474 </service-information>
475 <service-request-input>
476 </service-request-input>
477 </sdncadapterworkflow:SDNCRequestData>
478 </aetgt:SDNCAdapterWorkflowRequest>""".trim()
480 String sndcTopologyDeleteRequesAsString = utils.formatXml(sndcTopologyDeleteRequest)
481 logger.debug(sndcTopologyDeleteRequesAsString)
482 execution.setVariable("sdncAdapterWorkflowRequest", sndcTopologyDeleteRequesAsString)
483 logger.debug("sdncAdapterWorkflowRequest - " + "\n" + sndcTopologyDeleteRequesAsString)
485 } catch (Exception ex) {
486 String exceptionMessage = " Bpmn error encountered in DoDeleteResourcesV1 flow. prepareSDNCServiceRequest() - " + ex.getMessage()
487 logger.debug(exceptionMessage)
488 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, exceptionMessage)
491 logger.debug("***** Exit prepareSDNCServiceRequest for " + svcAction + "*****")