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=========================================================
23 package org.onap.so.bpmn.infrastructure.scripts;
25 import static org.apache.commons.lang3.StringUtils.*;
27 import javax.ws.rs.NotFoundException
29 import org.apache.commons.lang3.*
30 import org.camunda.bpm.engine.delegate.BpmnError
31 import org.camunda.bpm.engine.delegate.DelegateExecution
32 import org.json.JSONArray
33 import org.json.JSONObject
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.WorkflowException
39 import org.onap.so.bpmn.core.domain.Resource
40 import org.onap.so.bpmn.core.json.JsonUtils
41 import org.onap.so.bpmn.core.UrnPropertiesReader
42 import org.onap.so.client.aai.AAIObjectType
43 import org.onap.so.client.aai.AAIResourcesClient
44 import org.onap.so.client.aai.entities.AAIResultWrapper
45 import org.onap.so.client.aai.entities.uri.AAIResourceUri
46 import org.onap.so.client.aai.entities.uri.AAIUriFactory
47 import org.springframework.web.util.UriUtils
48 import org.slf4j.Logger
49 import org.slf4j.LoggerFactory
54 * This groovy class supports the <class>UpdateCustomE2EServiceInstance.bpmn</class> process.
55 * AlaCarte flow for 1702 ServiceInstance Update
58 public class UpdateCustomE2EServiceInstance extends AbstractServiceTaskProcessor {
59 private static final Logger logger = LoggerFactory.getLogger( UpdateCustomE2EServiceInstance.class);
61 String Prefix="UPDSI_"
62 ExceptionUtil exceptionUtil = new ExceptionUtil()
63 JsonUtils jsonUtil = new JsonUtils()
66 public void preProcessRequest (DelegateExecution execution) {
67 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
68 execution.setVariable("prefix",Prefix)
70 logger.info( " *** preProcessRequest() *** ")
74 String siRequest = execution.getVariable("bpmnRequest")
75 utils.logAudit(siRequest)
77 String requestId = execution.getVariable("mso-request-id")
78 execution.setVariable("msoRequestId", requestId)
79 logger.info( "Input Request:" + siRequest + " reqId:" + requestId)
81 String serviceInstanceId = execution.getVariable("serviceInstanceId")
82 if (isBlank(serviceInstanceId)) {
83 msg = "Input serviceInstanceId' is null"
84 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
87 //subscriberInfo for aai
88 String globalSubscriberId = jsonUtil.getJsonValue(siRequest, "requestDetails.subscriberInfo.globalSubscriberId")
89 if (isBlank(globalSubscriberId)) {
90 msg = "Input globalSubscriberId' is null"
91 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
93 execution.setVariable("globalSubscriberId", globalSubscriberId)
97 execution.setVariable("source", jsonUtil.getJsonValue(siRequest, "requestDetails.requestInfo.source"))
98 execution.setVariable("serviceInstanceName", jsonUtil.getJsonValue(siRequest, "requestDetails.requestInfo.instanceName"))
99 execution.setVariable("disableRollback", jsonUtil.getJsonValue(siRequest, "requestDetails.requestInfo.suppressRollback"))
100 String productFamilyId = jsonUtil.getJsonValue(siRequest, "requestDetails.requestInfo.productFamilyId")
101 if (isBlank(productFamilyId))
103 msg = "Input productFamilyId is null"
106 execution.setVariable("productFamilyId", productFamilyId)
110 String userParams = jsonUtil.getJsonValue(siRequest, "requestDetails.requestParameters.userParams")
111 logger.info( "userParams:" + userParams)
112 List<String> paramList = jsonUtil.StringArrayToList(execution, userParams)
113 String uuiRequest = jsonUtil.getJsonValue(paramList.get(0), "UUIRequest")
114 if (isBlank(uuiRequest)) {
115 msg = "Input uuiRequest is null"
117 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
120 execution.setVariable("uuiRequest", uuiRequest)
123 logger.info( "uuiRequest:\n" + uuiRequest)
125 //serviceType for aai
126 String serviceType = jsonUtil.getJsonValue(uuiRequest, "service.serviceType")
127 if (isBlank(serviceType)) {
128 msg = "Input serviceType is null"
130 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
132 execution.setVariable("serviceType", serviceType)
136 String modelInvariantUuid = jsonUtil.getJsonValue(uuiRequest, "service.serviceInvariantUuid")
137 logger.info("modelInvariantUuid: " + modelInvariantUuid)
138 execution.setVariable("modelInvariantUuid", modelInvariantUuid)
139 execution.setVariable("model-invariant-id-target", modelInvariantUuid)
141 String modelUuid = jsonUtil.getJsonValue(uuiRequest, "service.serviceUuid")
142 logger.info("modelUuid: " + modelUuid)
143 execution.setVariable("modelUuid", modelUuid)
144 execution.setVariable("model-version-id-target", modelUuid)
146 String serviceModelName = jsonUtil.getJsonValue(uuiRequest, "service.parameters.templateName")
147 logger.info("serviceModelName: " + serviceModelName)
148 if(serviceModelName == null) {
149 serviceModelName = ""
151 execution.setVariable("serviceModelName", serviceModelName)
154 String operationId = jsonUtil.getJsonValue(siRequest, "operationId")
155 if (isBlank(operationId)) {
156 operationId = UUID.randomUUID().toString()
158 execution.setVariable("operationId", operationId)
159 execution.setVariable("operationType", "update")
160 execution.setVariable("hasResourcetoUpdate", false)
162 } catch (BpmnError e) {
164 } catch (Exception ex){
165 msg = "Exception in preProcessRequest " + ex.getMessage()
167 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
169 logger.info(" ***** Exit preProcessRequest *****")
173 * Gets the service instance and its relationships from aai
175 public void getServiceInstance(DelegateExecution execution) {
177 String serviceInstanceId = execution.getVariable('serviceInstanceId')
178 String globalSubscriberId = execution.getVariable('globalSubscriberId')
179 String serviceType = execution.getVariable('serviceType')
181 AAIResourcesClient resourceClient = new AAIResourcesClient()
182 AAIResourceUri serviceInstanceUri = AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE, globalSubscriberId, serviceType, serviceInstanceId)
183 AAIResultWrapper wrapper = resourceClient.get(serviceInstanceUri, NotFoundException.class)
185 Optional<ServiceInstance> si = wrapper.asBean(ServiceInstance.class)
186 execution.setVariable("serviceInstanceName", si.get().getServiceInstanceName())
187 execution.setVariable("model-invariant-id-original", si.get().getModelInvariantId())
188 execution.setVariable("model-version-id-original", si.get().getModelVersionId())
190 JSONObject ob = new JSONObject(wrapper.getJson())
191 JSONArray ar = ob.getJSONObject("relationship-list").getJSONArray("relationship")
193 execution.setVariable("serviceRelationShip", ar.toString())
196 }catch(BpmnError e) {
198 }catch(NotFoundException e) {
199 exceptionUtil.buildAndThrowWorkflowException(execution, 404, "Service-instance does not exist AAI")
200 }catch(Exception ex) {
201 String msg = "Internal Error in getServiceInstance: " + ex.getMessage()
202 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
206 public void preCompareModelVersions(DelegateExecution execution) {
207 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
210 public void postCompareModelVersions(DelegateExecution execution) {
211 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
212 logger.debug( " ======== STARTED postCompareModelVersions Process ======== ")
214 def hasResourcetoUpdate = false
215 def hasResourcetoAdd = false
216 def hasResourcetoDelete = false
217 List<Resource> addResourceList = execution.getVariable("addResourceList")
218 List<Resource> delResourceList = execution.getVariable("delResourceList")
220 if(addResourceList != null && !addResourceList.isEmpty()) {
221 hasResourcetoAdd = true
224 if(delResourceList != null && !delResourceList.isEmpty()) {
225 hasResourcetoDelete = true
228 hasResourcetoUpdate = hasResourcetoAdd || hasResourcetoDelete
229 execution.setVariable("hasResourcetoUpdate", hasResourcetoUpdate)
231 logger.debug( "======== COMPLETED postCompareModelVersions Process ======== ")
235 * Init the service Operation Status
237 public void prepareInitServiceOperationStatus(DelegateExecution execution){
238 def isDebugEnabled = execution.getVariable("isDebugLogEnabled")
239 logger.debug( " ======== STARTED prepareInitServiceOperationStatus Process ======== ")
241 String serviceId = execution.getVariable("serviceInstanceId")
242 String operationId = execution.getVariable("operationId")
243 String operationType = execution.getVariable("operationType")
245 String result = "processing"
246 String progress = "0"
248 String operationContent = "Prepare service updating"
249 logger.debug( "Generated new operation for Service Instance serviceId:" + serviceId + " operationId:" + operationId)
250 serviceId = UriUtils.encode(serviceId,"UTF-8")
251 execution.setVariable("serviceInstanceId", serviceId)
252 execution.setVariable("operationId", operationId)
253 execution.setVariable("operationType", operationType)
255 def dbAdapterEndpoint = UrnPropertiesReader.getVariable("mso.adapters.openecomp.db.endpoint", execution)
256 execution.setVariable("CVFMI_dbAdapterEndpoint", dbAdapterEndpoint)
257 logger.debug( "DB Adapter Endpoint is: " + dbAdapterEndpoint)
260 """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
261 xmlns:ns="http://org.onap.so/requestsdb">
264 <ns:updateServiceOperationStatus xmlns:ns="http://org.onap.so/requestsdb">
265 <serviceId>${MsoUtils.xmlEscape(serviceId)}</serviceId>
266 <operationId>${MsoUtils.xmlEscape(operationId)}</operationId>
267 <operationType>${MsoUtils.xmlEscape(operationType)}</operationType>
268 <userId>${MsoUtils.xmlEscape(userId)}</userId>
269 <result>${MsoUtils.xmlEscape(result)}</result>
270 <operationContent>${MsoUtils.xmlEscape(operationContent)}</operationContent>
271 <progress>${MsoUtils.xmlEscape(progress)}</progress>
272 <reason>${MsoUtils.xmlEscape(reason)}</reason>
273 </ns:updateServiceOperationStatus>
275 </soapenv:Envelope>"""
277 payload = utils.formatXml(payload)
278 execution.setVariable("CVFMI_updateServiceOperStatusRequest", payload)
279 logger.error( "Outgoing updateServiceOperStatusRequest: \n" + payload)
280 utils.logAudit("CreateVfModuleInfra Outgoing updateServiceOperStatusRequest Request: " + payload)
283 logger.debug( "Exception Occured Processing prepareInitServiceOperationStatus. Exception is:\n" + e)
284 execution.setVariable("CVFMI_ErrorResponse", "Error Occurred during prepareInitServiceOperationStatus Method:\n" + e.getMessage())
286 logger.debug( "======== COMPLETED prepareInitServiceOperationStatus Process ======== ")
290 * Update the service Operation Status
292 public void preUpdateServiceOperationStatus(DelegateExecution execution){
293 def method = getClass().getSimpleName() + '.preUpdateServiceOperationStatus(' +'execution=' + execution.getId() +')'
294 def isDebugEnabled = execution.getVariable("isDebugLogEnabled")
295 logger.info("Entered " + method)
298 String serviceId = execution.getVariable("serviceInstanceId")
299 String operationId = execution.getVariable("operationId")
300 String operationType = execution.getVariable("operationType")
301 String serviceName = execution.getVariable("serviceInstanceName")
302 String result = execution.getVariable("operationResult")
303 String progress = execution.getVariable("progress")
304 String reason = execution.getVariable("operationReason")
306 logger.info( "progress: " + progress )
308 String operationContent = "Prepare service : " + execution.getVariable("operationStatus")
310 logger.info( "Generated new operation for Service Instance serviceId:" + serviceId + " operationId:" + operationId)
311 serviceId = UriUtils.encode(serviceId,"UTF-8")
312 execution.setVariable("serviceInstanceId", serviceId)
313 execution.setVariable("operationId", operationId)
314 execution.setVariable("operationType", operationType)
316 def dbAdapterEndpoint = UrnPropertiesReader.getVariable("mso.adapters.openecomp.db.endpoint", execution)
317 execution.setVariable("CVFMI_dbAdapterEndpoint", dbAdapterEndpoint)
318 logger.info( "DB Adapter Endpoint is: " + dbAdapterEndpoint)
321 """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
322 xmlns:ns="http://org.onap.so/requestsdb">
325 <ns:updateServiceOperationStatus xmlns:ns="http://org.onap.so/requestsdb">
326 <serviceId>${MsoUtils.xmlEscape(serviceId)}</serviceId>
327 <operationId>${MsoUtils.xmlEscape(operationId)}</operationId>
328 <operationType>${MsoUtils.xmlEscape(operationType)}</operationType>
329 <userId>${MsoUtils.xmlEscape(userId)}</userId>
330 <result>${MsoUtils.xmlEscape(result)}</result>
331 <operationContent>${MsoUtils.xmlEscape(operationContent)}</operationContent>
332 <progress>${MsoUtils.xmlEscape(progress)}</progress>
333 <reason>${MsoUtils.xmlEscape(reason)}</reason>
334 </ns:updateServiceOperationStatus>
336 </soapenv:Envelope>"""
338 payload = utils.formatXml(payload)
339 execution.setVariable("CVFMI_updateServiceOperStatusRequest", payload)
340 logger.error( "Outgoing preUpdateServiceOperationStatus: \n" + payload)
344 logger.info( "Exception Occured Processing preUpdateServiceOperationStatus. Exception is:\n" + e)
345 execution.setVariable("CVFMI_ErrorResponse", "Error Occurred during preUpdateServiceOperationStatus Method:\n" + e.getMessage())
347 logger.info( "======== COMPLETED preUpdateServiceOperationStatus Process ======== ")
348 logger.info( "Exited " + method)
351 public void sendSyncResponse (DelegateExecution execution) {
352 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
353 logger.info( " *** sendSyncResponse *** ")
356 String operationId = execution.getVariable("operationId")
357 def hasResourcetoUpdate = execution.getVariable("hasResourcetoUpdate")
359 String updateServiceResp = ""
360 if(hasResourcetoUpdate) {
361 // RESTResponse for API Handler (APIH) Reply Task
362 updateServiceResp = """{"operationId":"${operationId}"}""".trim()
365 updateServiceResp = """{"OperationResult":"No Resource to Add or Delete or Service Instance not found in AAI."}"""
368 logger.info( " sendSyncResponse to APIH:" + "\n" + updateServiceResp)
369 sendWorkflowResponse(execution, 202, updateServiceResp)
370 execution.setVariable("sentSyncResponse", true)
372 } catch (Exception ex) {
373 String msg = "Exceptuion in sendSyncResponse:" + ex.getMessage()
375 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
377 logger.info(" ***** Exit sendSyncResopnse *****")
380 public void sendSyncError (DelegateExecution execution) {
381 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
382 logger.info( " *** sendSyncError *** ")
385 String errorMessage = ""
387 if (execution.getVariable("WorkflowException") instanceof WorkflowException) {
388 WorkflowException wfe = execution.getVariable("WorkflowException")
389 errorMessage = wfe.getErrorMessage()
390 errorCode = wfe.getErrorCode()
392 errorMessage = "Sending Sync Error."
395 String buildworkflowException =
396 """<aetgt:WorkflowException xmlns:aetgt="http://org.onap/so/workflow/schema/v1">
397 <aetgt:ErrorMessage>${MsoUtils.xmlEscape(errorMessage)}</aetgt:ErrorMessage>
398 <aetgt:ErrorCode>${MsoUtils.xmlEscape(errorCode)}</aetgt:ErrorCode>
399 </aetgt:WorkflowException>"""
401 utils.logAudit(buildworkflowException)
402 sendWorkflowResponse(execution, 500, buildworkflowException)
404 } catch (Exception ex) {
405 logger.info( " Sending Sync Error Activity Failed. " + "\n" + ex.getMessage())
410 public void prepareCompletionRequest (DelegateExecution execution) {
411 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
412 logger.info( " *** prepareCompletion *** ")
415 String requestId = execution.getVariable("msoRequestId")
416 String serviceInstanceId = execution.getVariable("serviceInstanceId")
417 String source = execution.getVariable("source")
419 String msoCompletionRequest =
420 """<aetgt:MsoCompletionRequest xmlns:aetgt="http://org.onap/so/workflow/schema/v1"
421 xmlns:ns="http://org.onap/so/request/types/v1">
422 <request-info xmlns="http://org.onap/so/infra/vnf-request/v1">
423 <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
424 <action>UPDATE</action>
425 <source>${MsoUtils.xmlEscape(source)}</source>
427 <status-message>Service Instance was updated successfully.</status-message>
428 <serviceInstanceId>${MsoUtils.xmlEscape(serviceInstanceId)}</serviceInstanceId>
429 <mso-bpel-name>UpdateCustomE2EServiceInstance</mso-bpel-name>
430 </aetgt:MsoCompletionRequest>"""
433 String xmlMsoCompletionRequest = utils.formatXml(msoCompletionRequest)
435 execution.setVariable("completionRequest", xmlMsoCompletionRequest)
436 logger.info( " Overall SUCCESS Response going to CompleteMsoProcess - " + "\n" + xmlMsoCompletionRequest)
438 } catch (Exception ex) {
439 String msg = " Exception in prepareCompletion:" + ex.getMessage()
441 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
443 logger.info( "*** Exit prepareCompletionRequest ***")
446 public void prepareFalloutRequest(DelegateExecution execution){
447 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
448 logger.info( " *** prepareFalloutRequest *** ")
451 WorkflowException wfex = execution.getVariable("WorkflowException")
452 logger.info( " Input Workflow Exception: " + wfex.toString())
453 String requestId = execution.getVariable("msoRequestId")
454 String source = execution.getVariable("source")
456 """<request-info xmlns="http://org.onap/so/infra/vnf-request/v1">
457 <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
458 <action>UPDATE</action>
459 <source>${MsoUtils.xmlEscape(source)}</source>
462 String falloutRequest = exceptionUtil.processMainflowsBPMNException(execution, requestInfo)
463 execution.setVariable("falloutRequest", falloutRequest)
464 } catch (Exception ex) {
465 logger.info( "Exception prepareFalloutRequest:" + ex.getMessage())
466 String errorException = " Bpmn error encountered in UpdateCustomE2EServiceInstance flow. FalloutHandlerRequest, buildErrorResponse() - " + ex.getMessage()
467 String requestId = execution.getVariable("msoRequestId")
468 String falloutRequest =
469 """<aetgt:FalloutHandlerRequest xmlns:aetgt="http://org.onap/so/workflow/schema/v1"
470 xmlns:ns="http://org.onap/so/request/types/v1"
471 xmlns:wfsch="http://org.onap/so/workflow/schema/v1">
472 <request-info xmlns="http://org.onap/so/infra/vnf-request/v1">
473 <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
474 <action>UPDATE</action>
477 <aetgt:WorkflowException xmlns:aetgt="http://org.onap/so/workflow/schema/v1">
478 <aetgt:ErrorMessage>${MsoUtils.xmlEscape(errorException)}</aetgt:ErrorMessage>
479 <aetgt:ErrorCode>7000</aetgt:ErrorCode>
480 </aetgt:WorkflowException>
481 </aetgt:FalloutHandlerRequest>"""
483 execution.setVariable("falloutRequest", falloutRequest)
485 logger.info( "*** Exit prepareFalloutRequest ***")