2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. 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=========================================================
23 package org.onap.so.bpmn.infrastructure.scripts
25 import static org.apache.commons.lang3.StringUtils.*;
27 import org.apache.commons.lang3.*
28 import org.camunda.bpm.engine.delegate.BpmnError
29 import org.camunda.bpm.engine.delegate.DelegateExecution
30 import org.onap.aai.domain.yang.ServiceInstance
31 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor
32 import org.onap.so.bpmn.common.scripts.ExceptionUtil
33 import org.onap.so.bpmn.common.scripts.MsoUtils
34 import org.onap.so.bpmn.common.scripts.SDNCAdapterUtils
35 import org.onap.so.bpmn.core.UrnPropertiesReader;
36 import org.onap.so.bpmn.core.WorkflowException
37 import org.onap.so.bpmn.core.json.JsonUtils
38 import org.onap.so.client.aai.AAIObjectType
39 import org.onap.so.client.aai.AAIResourcesClient
40 import org.onap.so.client.aai.entities.AAIResultWrapper
41 import org.onap.so.client.aai.entities.uri.AAIResourceUri
42 import org.onap.so.client.aai.entities.uri.AAIUriFactory
43 import org.slf4j.Logger
44 import org.slf4j.LoggerFactory
45 import org.springframework.web.util.UriUtils;
50 * This groovy class supports the <class>DoDeleteServiceInstance.bpmn</class> process.
53 * @param - msoRequestId
54 * @param - globalSubscriberId - O
55 * @param - subscriptionServiceType - O
56 * @param - serviceInstanceId
57 * @param - serviceInstanceName - O
58 * @param - serviceModelInfo - O
59 * @param - productFamilyId
60 * @param - serviceInputParams (should contain aic_zone for serviceTypes TRANSPORT,ATM)
61 * @param - sdncVersion
62 * @param - failNotFound - TODO
63 * @param - serviceInputParams - TODO
66 * @param - WorkflowException
70 public class DoDeleteServiceInstance extends AbstractServiceTaskProcessor {
71 private static final Logger logger = LoggerFactory.getLogger( DoDeleteServiceInstance.class);
73 String Prefix="DDELSI_"
74 ExceptionUtil exceptionUtil = new ExceptionUtil()
75 JsonUtils jsonUtil = new JsonUtils()
77 public void preProcessRequest (DelegateExecution execution) {
79 logger.trace("preProcessRequest ")
83 String requestId = execution.getVariable("msoRequestId")
84 execution.setVariable("prefix",Prefix)
87 //requestDetails.subscriberInfo. for AAI GET & PUT & SDNC assignToplology
88 String globalSubscriberId = execution.getVariable("globalSubscriberId") //globalCustomerId
89 if (globalSubscriberId == null)
91 execution.setVariable("globalSubscriberId", "")
94 //requestDetails.requestParameters. for AAI PUT & SDNC assignTopology
95 String subscriptionServiceType = execution.getVariable("subscriptionServiceType")
96 if (subscriptionServiceType == null)
98 execution.setVariable("subscriptionServiceType", "")
101 //Generated in parent for AAI PUT
102 String serviceInstanceId = execution.getVariable("serviceInstanceId")
103 if (isBlank(serviceInstanceId)){
104 msg = "Input serviceInstanceId is null"
106 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
109 String sdncCallbackUrl = UrnPropertiesReader.getVariable('mso.workflow.sdncadapter.callback',execution)
110 if (isBlank(sdncCallbackUrl)) {
111 msg = "mso.workflow.sdncadapter.callback is null"
113 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
115 execution.setVariable("sdncCallbackUrl", sdncCallbackUrl)
116 logger.debug("SDNC Callback URL: " + sdncCallbackUrl)
118 StringBuilder sbParams = new StringBuilder()
119 Map<String, String> paramsMap = execution.getVariable("serviceInputParams")
120 if (paramsMap != null)
122 sbParams.append("<service-input-parameters>")
123 for (Map.Entry<String, String> entry : paramsMap.entrySet()) {
125 String paramName = entry.getKey()
126 String paramValue = entry.getValue()
129 <name>${MsoUtils.xmlEscape(paramName)}</name>
130 <value>${MsoUtils.xmlEscape(paramValue)}</value>
133 sbParams.append(paramsXml)
135 sbParams.append("</service-input-parameters>")
137 String siParamsXml = sbParams.toString()
138 if (siParamsXml == null)
140 execution.setVariable("siParamsXml", siParamsXml)
142 } catch (BpmnError e) {
144 } catch (Exception ex){
145 msg = "Exception in preProcessRequest " + ex.getMessage()
147 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
149 logger.trace("Exit preProcessRequest ")
152 public void preProcessSDNCDelete (DelegateExecution execution) {
154 logger.trace("preProcessSDNCDelete ")
158 def serviceInstanceId = execution.getVariable("serviceInstanceId") ?: ""
159 def serviceInstanceName = execution.getVariable("serviceInstanceName") ?: ""
160 def callbackURL = execution.getVariable("sdncCallbackUrl") ?: ""
161 def requestId = execution.getVariable("msoRequestId") ?: ""
162 def serviceId = execution.getVariable("productFamilyId") ?: ""
163 def subscriptionServiceType = execution.getVariable("subscriptionServiceType") ?: ""
164 def globalSubscriberId = execution.getVariable("globalSubscriberId") ?: "" //globalCustomerId
166 String serviceModelInfo = execution.getVariable("serviceModelInfo") ?: ""
167 def modelInvariantUuid = ""
168 def modelVersion = ""
171 if (!isBlank(serviceModelInfo))
173 modelInvariantUuid = jsonUtil.getJsonValue(serviceModelInfo, "modelInvariantUuid") ?: ""
174 modelVersion = jsonUtil.getJsonValue(serviceModelInfo, "modelVersion") ?: ""
175 modelUuid = jsonUtil.getJsonValue(serviceModelInfo, "modelUuid") ?: ""
176 modelName = jsonUtil.getJsonValue(serviceModelInfo, "modelName") ?: ""
180 def siParamsXml = execution.getVariable("siParamsXml") ?: ""
182 // special URL for SDNW, msoAction helps set diff url in SDNCA
183 if("TRANSPORT".equalsIgnoreCase(execution.getVariable("serviceType")))
185 msoAction = "TRANSPORT"
188 def sdncRequestId = UUID.randomUUID().toString()
191 """<sdncadapterworkflow:SDNCAdapterWorkflowRequest xmlns:ns5="http://org.onap/so/request/types/v1"
192 xmlns:sdncadapterworkflow="http://org.onap/so/workflow/schema/v1"
193 xmlns:sdncadapter="http://org.onap/workflow/sdnc/adapter/schema/v1">
194 <sdncadapter:RequestHeader>
195 <sdncadapter:RequestId>${MsoUtils.xmlEscape(sdncRequestId)}</sdncadapter:RequestId>
196 <sdncadapter:SvcInstanceId>${MsoUtils.xmlEscape(serviceInstanceId)}</sdncadapter:SvcInstanceId>
197 <sdncadapter:SvcAction>delete</sdncadapter:SvcAction>
198 <sdncadapter:SvcOperation>service-topology-operation</sdncadapter:SvcOperation>
199 <sdncadapter:CallbackUrl>${MsoUtils.xmlEscape(callbackURL)}</sdncadapter:CallbackUrl>
200 <sdncadapter:MsoAction>${MsoUtils.xmlEscape(msoAction)}</sdncadapter:MsoAction>
201 </sdncadapter:RequestHeader>
202 <sdncadapterworkflow:SDNCRequestData>
203 <request-information>
204 <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
209 <request-action>DeleteServiceInstance</request-action>
210 </request-information>
211 <service-information>
212 <service-id>${MsoUtils.xmlEscape(serviceId)}</service-id>
213 <subscription-service-type>${MsoUtils.xmlEscape(subscriptionServiceType)}</subscription-service-type>
214 <onap-model-information>
215 <model-invariant-uuid>${MsoUtils.xmlEscape(modelInvariantUuid)}</model-invariant-uuid>
216 <model-uuid>${MsoUtils.xmlEscape(modelUuid)}</model-uuid>
217 <model-version>${MsoUtils.xmlEscape(modelVersion)}</model-version>
218 <model-name>${MsoUtils.xmlEscape(modelName)}</model-name>
219 </onap-model-information>
220 <service-instance-id>${MsoUtils.xmlEscape(serviceInstanceId)}</service-instance-id>
222 <global-customer-id>${MsoUtils.xmlEscape(globalSubscriberId)}</global-customer-id>
223 </service-information>
224 <service-request-input>
225 <service-instance-name>${MsoUtils.xmlEscape(serviceInstanceName)}</service-instance-name>
227 </service-request-input>
228 </sdncadapterworkflow:SDNCRequestData>
229 </sdncadapterworkflow:SDNCAdapterWorkflowRequest>"""
231 sdncDelete = utils.formatXml(sdncDelete)
232 def sdncRequestId2 = UUID.randomUUID().toString()
233 String sdncDeactivate = sdncDelete.replace(">delete<", ">deactivate<").replace(">${sdncRequestId}<", ">${sdncRequestId2}<")
234 execution.setVariable("sdncDelete", sdncDelete)
235 execution.setVariable("sdncDeactivate", sdncDeactivate)
236 logger.debug("sdncDeactivate:\n" + sdncDeactivate)
237 logger.debug("sdncDelete:\n" + sdncDelete)
239 } catch (BpmnError e) {
241 } catch(Exception ex) {
242 msg = "Exception in preProcessSDNCDelete. " + ex.getMessage()
244 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, "Exception Occured in preProcessSDNCDelete.\n" + ex.getMessage())
246 logger.debug(" *****Exit preProcessSDNCDelete *****")
249 public void postProcessSDNCDelete(DelegateExecution execution, String response, String method) {
252 logger.trace("postProcessSDNC " + method + " ")
256 WorkflowException workflowException = execution.getVariable("WorkflowException")
257 boolean successIndicator = execution.getVariable("SDNCA_SuccessIndicator")
258 logger.debug("SDNCResponse: " + response)
259 logger.debug("workflowException: " + workflowException)
261 SDNCAdapterUtils sdncAdapterUtils = new SDNCAdapterUtils()
262 sdncAdapterUtils.validateSDNCResponse(execution, response, workflowException, successIndicator)
264 if(execution.getVariable(Prefix + 'sdncResponseSuccess') == true){
265 logger.debug("Good response from SDNC Adapter for service-instance " + method + "response:\n" + response)
268 msg = "Bad Response from SDNC Adapter for service-instance " + method
270 exceptionUtil.buildAndThrowWorkflowException(execution, 3500, msg)
272 } catch (BpmnError e) {
274 } catch(Exception ex) {
275 msg = "Exception in postProcessSDNC " + method + " Exception:" + ex.getMessage()
277 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
279 logger.trace("Exit postProcessSDNC " + method + " ")
283 * Gets the service instance uri from aai
285 public void getServiceInstance(DelegateExecution execution) {
286 logger.trace("getServiceInstance ")
288 String serviceInstanceId = execution.getVariable('serviceInstanceId')
290 AAIResourcesClient resourceClient = new AAIResourcesClient()
291 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE, serviceInstanceId)
293 if(resourceClient.exists(uri)){
294 execution.setVariable("GENGS_FoundIndicator", true)
295 execution.setVariable("GENGS_siResourceLink", uri.build().toString())
296 Map<String, String> keys = uri.getURIKeys()
297 String globalSubscriberId = execution.getVariable("globalSubscriberId")
298 if(isBlank(globalSubscriberId)){
299 globalSubscriberId = keys.get("global-customer-id")
300 execution.setVariable("globalSubscriberId", globalSubscriberId)
303 //Extract Service Type if not provided on request
304 String subscriptionServiceType = execution.getVariable("subscriptionServiceType")
305 if(isBlank(subscriptionServiceType)){
306 String serviceTypeEncoded = keys.get("service-type") //TODO will this produce as already decoded?
307 subscriptionServiceType = UriUtils.decode(serviceTypeEncoded, "UTF-8")
308 execution.setVariable("subscriptionServiceType", subscriptionServiceType)
311 AAIResultWrapper wrapper = resourceClient.get(uri)
312 if(wrapper.getRelationships().isPresent()){
313 List<AAIResourceUri> uriList = wrapper.getRelationships().get().getRelatedAAIUris(AAIObjectType.ALLOTTED_RESOURCE)
314 uriList.addAll(wrapper.getRelationships().get().getRelatedAAIUris(AAIObjectType.GENERIC_VNF))
315 uriList.addAll(wrapper.getRelationships().get().getRelatedAAIUris(AAIObjectType.L3_NETWORK))
317 if(uriList.isEmpty()){
318 Optional<ServiceInstance> si = wrapper.asBean(ServiceInstance.class)
319 String orchestrationStatus = si.get().getOrchestrationStatus()
320 String serviceType = si.get().getServiceType()
321 execution.setVariable("serviceType", serviceType)
322 execution.setVariable("serviceRole", si.get().getServiceRole())
324 if("TRANSPORT".equalsIgnoreCase(serviceType)){
325 if("PendingDelete".equals(orchestrationStatus)){
326 execution.setVariable("skipDeactivate", true)
328 exceptionUtil.buildAndThrowWorkflowException(execution, 500, "ServiceInstance of type TRANSPORT must in PendingDelete status to allow Delete. Orchestration-status: " + orchestrationStatus)
332 String svcTypes = UrnPropertiesReader.getVariable("sdnc.si.svc.types",execution) ?: ""
333 List<String> svcList = Arrays.asList(svcTypes.split("\\s*,\\s*"));
334 boolean isSdncService= false
335 for(String listEntry : svcList){
336 if(listEntry.equalsIgnoreCase(serviceType)){
341 execution.setVariable("sendToSDNC", true)
342 if(execution.getVariable("sdncVersion").equals("1610")){
344 execution.setVariable("sendToSDNC", false)
349 execution.setVariable("siInUse", true)
350 logger.debug("Stopped deleting Service Instance, it has dependencies")
351 exceptionUtil.buildAndThrowWorkflowException(execution, 500, "Stopped deleting Service Instance, it has dependencies")
355 exceptionUtil.buildAndThrowWorkflowException(execution, 500, "ServiceInstance not found in aai")
358 }catch(BpmnError e) {
360 }catch (Exception ex){
361 String msg = "Exception in getServiceInstance. " + ex.getMessage()
363 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
368 * Deletes the service instance in aai
370 public void deleteServiceInstance(DelegateExecution execution) {
371 logger.trace("Entered deleteServiceInstance")
373 String globalCustId = execution.getVariable("globalSubscriberId")
374 String serviceType = execution.getVariable("subscriptionServiceType")
375 String serviceInstanceId = execution.getVariable("serviceInstanceId")
377 AAIResourcesClient resourceClient = new AAIResourcesClient();
378 AAIResourceUri serviceInstanceUri = AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE, globalCustId, serviceType, serviceInstanceId)
379 resourceClient.delete(serviceInstanceUri)
381 logger.trace("Exited deleteServiceInstance")
383 logger.debug("Error occured within deleteServiceInstance method: " + e)
384 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Error occured during deleteServiceInstance from aai")