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")
76 String requestId = execution.getVariable("mso-request-id")
77 execution.setVariable("msoRequestId", requestId)
78 logger.info( "Input Request:" + siRequest + " reqId:" + requestId)
80 String serviceInstanceId = execution.getVariable("serviceInstanceId")
81 if (isBlank(serviceInstanceId)) {
82 msg = "Input serviceInstanceId' is null"
83 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
86 //subscriberInfo for aai
87 String globalSubscriberId = jsonUtil.getJsonValue(siRequest, "requestDetails.subscriberInfo.globalSubscriberId")
88 if (isBlank(globalSubscriberId)) {
89 msg = "Input globalSubscriberId' is null"
90 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
92 execution.setVariable("globalSubscriberId", globalSubscriberId)
96 execution.setVariable("source", jsonUtil.getJsonValue(siRequest, "requestDetails.requestInfo.source"))
97 execution.setVariable("serviceInstanceName", jsonUtil.getJsonValue(siRequest, "requestDetails.requestInfo.instanceName"))
98 execution.setVariable("disableRollback", jsonUtil.getJsonValue(siRequest, "requestDetails.requestInfo.suppressRollback"))
99 String productFamilyId = jsonUtil.getJsonValue(siRequest, "requestDetails.requestInfo.productFamilyId")
100 if (isBlank(productFamilyId))
102 msg = "Input productFamilyId is null"
105 execution.setVariable("productFamilyId", productFamilyId)
109 String userParams = jsonUtil.getJsonValue(siRequest, "requestDetails.requestParameters.userParams")
110 logger.info( "userParams:" + userParams)
111 List<String> paramList = jsonUtil.StringArrayToList(execution, userParams)
112 String uuiRequest = jsonUtil.getJsonValue(paramList.get(0), "UUIRequest")
113 if (isBlank(uuiRequest)) {
114 msg = "Input uuiRequest is null"
116 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
119 execution.setVariable("uuiRequest", uuiRequest)
122 logger.info( "uuiRequest:\n" + uuiRequest)
124 //serviceType for aai
125 String serviceType = jsonUtil.getJsonValue(uuiRequest, "service.serviceType")
126 if (isBlank(serviceType)) {
127 msg = "Input serviceType is null"
129 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
131 execution.setVariable("serviceType", serviceType)
135 String modelInvariantUuid = jsonUtil.getJsonValue(uuiRequest, "service.serviceInvariantUuid")
136 logger.info("modelInvariantUuid: " + modelInvariantUuid)
137 execution.setVariable("modelInvariantUuid", modelInvariantUuid)
138 execution.setVariable("model-invariant-id-target", modelInvariantUuid)
140 String modelUuid = jsonUtil.getJsonValue(uuiRequest, "service.serviceUuid")
141 logger.info("modelUuid: " + modelUuid)
142 execution.setVariable("modelUuid", modelUuid)
143 execution.setVariable("model-version-id-target", modelUuid)
145 String serviceModelName = jsonUtil.getJsonValue(uuiRequest, "service.parameters.templateName")
146 logger.info("serviceModelName: " + serviceModelName)
147 if(serviceModelName == null) {
148 serviceModelName = ""
150 execution.setVariable("serviceModelName", serviceModelName)
153 String operationId = jsonUtil.getJsonValue(siRequest, "operationId")
154 if (isBlank(operationId)) {
155 operationId = UUID.randomUUID().toString()
157 execution.setVariable("operationId", operationId)
158 execution.setVariable("operationType", "update")
159 execution.setVariable("hasResourcetoUpdate", false)
161 } catch (BpmnError e) {
163 } catch (Exception ex){
164 msg = "Exception in preProcessRequest " + ex.getMessage()
166 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
168 logger.info(" ***** Exit preProcessRequest *****")
172 * Gets the service instance and its relationships from aai
174 public void getServiceInstance(DelegateExecution execution) {
176 String serviceInstanceId = execution.getVariable('serviceInstanceId')
177 String globalSubscriberId = execution.getVariable('globalSubscriberId')
178 String serviceType = execution.getVariable('serviceType')
180 AAIResourcesClient resourceClient = new AAIResourcesClient()
181 AAIResourceUri serviceInstanceUri = AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE, globalSubscriberId, serviceType, serviceInstanceId)
182 AAIResultWrapper wrapper = resourceClient.get(serviceInstanceUri, NotFoundException.class)
184 Optional<ServiceInstance> si = wrapper.asBean(ServiceInstance.class)
185 execution.setVariable("serviceInstanceName", si.get().getServiceInstanceName())
186 execution.setVariable("model-invariant-id-original", si.get().getModelInvariantId())
187 execution.setVariable("model-version-id-original", si.get().getModelVersionId())
189 JSONObject ob = new JSONObject(wrapper.getJson())
190 JSONArray ar = ob.getJSONObject("relationship-list").getJSONArray("relationship")
192 execution.setVariable("serviceRelationShip", ar.toString())
195 }catch(BpmnError e) {
197 }catch(NotFoundException e) {
198 exceptionUtil.buildAndThrowWorkflowException(execution, 404, "Service-instance does not exist AAI")
199 }catch(Exception ex) {
200 String msg = "Internal Error in getServiceInstance: " + ex.getMessage()
201 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
205 public void preCompareModelVersions(DelegateExecution execution) {
206 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
209 public void postCompareModelVersions(DelegateExecution execution) {
210 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
211 logger.debug( " ======== STARTED postCompareModelVersions Process ======== ")
213 def hasResourcetoUpdate = false
214 def hasResourcetoAdd = false
215 def hasResourcetoDelete = false
216 List<Resource> addResourceList = execution.getVariable("addResourceList")
217 List<Resource> delResourceList = execution.getVariable("delResourceList")
219 if(addResourceList != null && !addResourceList.isEmpty()) {
220 hasResourcetoAdd = true
223 if(delResourceList != null && !delResourceList.isEmpty()) {
224 hasResourcetoDelete = true
227 hasResourcetoUpdate = hasResourcetoAdd || hasResourcetoDelete
228 execution.setVariable("hasResourcetoUpdate", hasResourcetoUpdate)
230 logger.debug( "======== COMPLETED postCompareModelVersions Process ======== ")
234 * Init the service Operation Status
236 public void prepareInitServiceOperationStatus(DelegateExecution execution){
237 def isDebugEnabled = execution.getVariable("isDebugLogEnabled")
238 logger.debug( " ======== STARTED prepareInitServiceOperationStatus Process ======== ")
240 String serviceId = execution.getVariable("serviceInstanceId")
241 String operationId = execution.getVariable("operationId")
242 String operationType = execution.getVariable("operationType")
244 String result = "processing"
245 String progress = "0"
247 String operationContent = "Prepare service updating"
248 logger.debug( "Generated new operation for Service Instance serviceId:" + serviceId + " operationId:" + operationId)
249 serviceId = UriUtils.encode(serviceId,"UTF-8")
250 execution.setVariable("serviceInstanceId", serviceId)
251 execution.setVariable("operationId", operationId)
252 execution.setVariable("operationType", operationType)
254 def dbAdapterEndpoint = UrnPropertiesReader.getVariable("mso.adapters.openecomp.db.endpoint", execution)
255 execution.setVariable("CVFMI_dbAdapterEndpoint", dbAdapterEndpoint)
256 logger.debug( "DB Adapter Endpoint is: " + dbAdapterEndpoint)
259 """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
260 xmlns:ns="http://org.onap.so/requestsdb">
263 <ns:updateServiceOperationStatus xmlns:ns="http://org.onap.so/requestsdb">
264 <serviceId>${MsoUtils.xmlEscape(serviceId)}</serviceId>
265 <operationId>${MsoUtils.xmlEscape(operationId)}</operationId>
266 <operationType>${MsoUtils.xmlEscape(operationType)}</operationType>
267 <userId>${MsoUtils.xmlEscape(userId)}</userId>
268 <result>${MsoUtils.xmlEscape(result)}</result>
269 <operationContent>${MsoUtils.xmlEscape(operationContent)}</operationContent>
270 <progress>${MsoUtils.xmlEscape(progress)}</progress>
271 <reason>${MsoUtils.xmlEscape(reason)}</reason>
272 </ns:updateServiceOperationStatus>
274 </soapenv:Envelope>"""
276 payload = utils.formatXml(payload)
277 execution.setVariable("CVFMI_updateServiceOperStatusRequest", payload)
278 logger.error( "Outgoing updateServiceOperStatusRequest: \n" + payload)
281 logger.debug( "Exception Occured Processing prepareInitServiceOperationStatus. Exception is:\n" + e)
282 execution.setVariable("CVFMI_ErrorResponse", "Error Occurred during prepareInitServiceOperationStatus Method:\n" + e.getMessage())
284 logger.debug( "======== COMPLETED prepareInitServiceOperationStatus Process ======== ")
288 * Update the service Operation Status
290 public void preUpdateServiceOperationStatus(DelegateExecution execution){
291 def method = getClass().getSimpleName() + '.preUpdateServiceOperationStatus(' +'execution=' + execution.getId() +')'
292 def isDebugEnabled = execution.getVariable("isDebugLogEnabled")
293 logger.info("Entered " + method)
296 String serviceId = execution.getVariable("serviceInstanceId")
297 String operationId = execution.getVariable("operationId")
298 String operationType = execution.getVariable("operationType")
299 String serviceName = execution.getVariable("serviceInstanceName")
300 String result = execution.getVariable("operationResult")
301 String progress = execution.getVariable("progress")
302 String reason = execution.getVariable("operationReason")
304 logger.info( "progress: " + progress )
306 String operationContent = "Prepare service : " + execution.getVariable("operationStatus")
308 logger.info( "Generated new operation for Service Instance serviceId:" + serviceId + " operationId:" + operationId)
309 serviceId = UriUtils.encode(serviceId,"UTF-8")
310 execution.setVariable("serviceInstanceId", serviceId)
311 execution.setVariable("operationId", operationId)
312 execution.setVariable("operationType", operationType)
314 def dbAdapterEndpoint = UrnPropertiesReader.getVariable("mso.adapters.openecomp.db.endpoint", execution)
315 execution.setVariable("CVFMI_dbAdapterEndpoint", dbAdapterEndpoint)
316 logger.info( "DB Adapter Endpoint is: " + dbAdapterEndpoint)
319 """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
320 xmlns:ns="http://org.onap.so/requestsdb">
323 <ns:updateServiceOperationStatus xmlns:ns="http://org.onap.so/requestsdb">
324 <serviceId>${MsoUtils.xmlEscape(serviceId)}</serviceId>
325 <operationId>${MsoUtils.xmlEscape(operationId)}</operationId>
326 <operationType>${MsoUtils.xmlEscape(operationType)}</operationType>
327 <userId>${MsoUtils.xmlEscape(userId)}</userId>
328 <result>${MsoUtils.xmlEscape(result)}</result>
329 <operationContent>${MsoUtils.xmlEscape(operationContent)}</operationContent>
330 <progress>${MsoUtils.xmlEscape(progress)}</progress>
331 <reason>${MsoUtils.xmlEscape(reason)}</reason>
332 </ns:updateServiceOperationStatus>
334 </soapenv:Envelope>"""
336 payload = utils.formatXml(payload)
337 execution.setVariable("CVFMI_updateServiceOperStatusRequest", payload)
338 logger.error( "Outgoing preUpdateServiceOperationStatus: \n" + payload)
342 logger.info( "Exception Occured Processing preUpdateServiceOperationStatus. Exception is:\n" + e)
343 execution.setVariable("CVFMI_ErrorResponse", "Error Occurred during preUpdateServiceOperationStatus Method:\n" + e.getMessage())
345 logger.info( "======== COMPLETED preUpdateServiceOperationStatus Process ======== ")
346 logger.info( "Exited " + method)
349 public void sendSyncResponse (DelegateExecution execution) {
350 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
351 logger.info( " *** sendSyncResponse *** ")
354 String operationId = execution.getVariable("operationId")
355 def hasResourcetoUpdate = execution.getVariable("hasResourcetoUpdate")
357 String updateServiceResp = ""
358 if(hasResourcetoUpdate) {
359 // RESTResponse for API Handler (APIH) Reply Task
360 updateServiceResp = """{"operationId":"${operationId}"}""".trim()
363 updateServiceResp = """{"OperationResult":"No Resource to Add or Delete or Service Instance not found in AAI."}"""
366 logger.info( " sendSyncResponse to APIH:" + "\n" + updateServiceResp)
367 sendWorkflowResponse(execution, 202, updateServiceResp)
368 execution.setVariable("sentSyncResponse", true)
370 } catch (Exception ex) {
371 String msg = "Exceptuion in sendSyncResponse:" + ex.getMessage()
373 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
375 logger.info(" ***** Exit sendSyncResopnse *****")
378 public void sendSyncError (DelegateExecution execution) {
379 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
380 logger.info( " *** sendSyncError *** ")
383 String errorMessage = ""
385 if (execution.getVariable("WorkflowException") instanceof WorkflowException) {
386 WorkflowException wfe = execution.getVariable("WorkflowException")
387 errorMessage = wfe.getErrorMessage()
388 errorCode = wfe.getErrorCode()
390 errorMessage = "Sending Sync Error."
393 String buildworkflowException =
394 """<aetgt:WorkflowException xmlns:aetgt="http://org.onap/so/workflow/schema/v1">
395 <aetgt:ErrorMessage>${MsoUtils.xmlEscape(errorMessage)}</aetgt:ErrorMessage>
396 <aetgt:ErrorCode>${MsoUtils.xmlEscape(errorCode)}</aetgt:ErrorCode>
397 </aetgt:WorkflowException>"""
399 sendWorkflowResponse(execution, 500, buildworkflowException)
401 } catch (Exception ex) {
402 logger.info( " Sending Sync Error Activity Failed. " + "\n" + ex.getMessage())
407 public void prepareCompletionRequest (DelegateExecution execution) {
408 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
409 logger.info( " *** prepareCompletion *** ")
412 String requestId = execution.getVariable("msoRequestId")
413 String serviceInstanceId = execution.getVariable("serviceInstanceId")
414 String source = execution.getVariable("source")
416 String msoCompletionRequest =
417 """<aetgt:MsoCompletionRequest xmlns:aetgt="http://org.onap/so/workflow/schema/v1"
418 xmlns:ns="http://org.onap/so/request/types/v1">
419 <request-info xmlns="http://org.onap/so/infra/vnf-request/v1">
420 <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
421 <action>UPDATE</action>
422 <source>${MsoUtils.xmlEscape(source)}</source>
424 <status-message>Service Instance was updated successfully.</status-message>
425 <serviceInstanceId>${MsoUtils.xmlEscape(serviceInstanceId)}</serviceInstanceId>
426 <mso-bpel-name>UpdateCustomE2EServiceInstance</mso-bpel-name>
427 </aetgt:MsoCompletionRequest>"""
430 String xmlMsoCompletionRequest = utils.formatXml(msoCompletionRequest)
432 execution.setVariable("completionRequest", xmlMsoCompletionRequest)
433 logger.info( " Overall SUCCESS Response going to CompleteMsoProcess - " + "\n" + xmlMsoCompletionRequest)
435 } catch (Exception ex) {
436 String msg = " Exception in prepareCompletion:" + ex.getMessage()
438 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
440 logger.info( "*** Exit prepareCompletionRequest ***")
443 public void prepareFalloutRequest(DelegateExecution execution){
444 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
445 logger.info( " *** prepareFalloutRequest *** ")
448 WorkflowException wfex = execution.getVariable("WorkflowException")
449 logger.info( " Input Workflow Exception: " + wfex.toString())
450 String requestId = execution.getVariable("msoRequestId")
451 String source = execution.getVariable("source")
453 """<request-info xmlns="http://org.onap/so/infra/vnf-request/v1">
454 <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
455 <action>UPDATE</action>
456 <source>${MsoUtils.xmlEscape(source)}</source>
459 String falloutRequest = exceptionUtil.processMainflowsBPMNException(execution, requestInfo)
460 execution.setVariable("falloutRequest", falloutRequest)
461 } catch (Exception ex) {
462 logger.info( "Exception prepareFalloutRequest:" + ex.getMessage())
463 String errorException = " Bpmn error encountered in UpdateCustomE2EServiceInstance flow. FalloutHandlerRequest, buildErrorResponse() - " + ex.getMessage()
464 String requestId = execution.getVariable("msoRequestId")
465 String falloutRequest =
466 """<aetgt:FalloutHandlerRequest xmlns:aetgt="http://org.onap/so/workflow/schema/v1"
467 xmlns:ns="http://org.onap/so/request/types/v1"
468 xmlns:wfsch="http://org.onap/so/workflow/schema/v1">
469 <request-info xmlns="http://org.onap/so/infra/vnf-request/v1">
470 <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
471 <action>UPDATE</action>
474 <aetgt:WorkflowException xmlns:aetgt="http://org.onap/so/workflow/schema/v1">
475 <aetgt:ErrorMessage>${MsoUtils.xmlEscape(errorException)}</aetgt:ErrorMessage>
476 <aetgt:ErrorCode>7000</aetgt:ErrorCode>
477 </aetgt:WorkflowException>
478 </aetgt:FalloutHandlerRequest>"""
480 execution.setVariable("falloutRequest", falloutRequest)
482 logger.info( "*** Exit prepareFalloutRequest ***")