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("serviceInstanceData-original", si.get())
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)
282 logger.debug( "Exception Occured Processing prepareInitServiceOperationStatus. Exception is:\n" + e)
283 execution.setVariable("CVFMI_ErrorResponse", "Error Occurred during prepareInitServiceOperationStatus Method:\n" + e.getMessage())
285 logger.debug( "======== COMPLETED prepareInitServiceOperationStatus Process ======== ")
289 * Update the service Operation Status
291 public void preUpdateServiceOperationStatus(DelegateExecution execution){
292 def method = getClass().getSimpleName() + '.preUpdateServiceOperationStatus(' +'execution=' + execution.getId() +')'
293 def isDebugEnabled = execution.getVariable("isDebugLogEnabled")
294 logger.info("Entered " + method)
297 String serviceId = execution.getVariable("serviceInstanceId")
298 String operationId = execution.getVariable("operationId")
299 String operationType = execution.getVariable("operationType")
300 String serviceName = execution.getVariable("serviceInstanceName")
301 String result = execution.getVariable("operationResult")
302 String progress = execution.getVariable("progress")
303 String reason = execution.getVariable("operationReason")
305 logger.info( "progress: " + progress )
307 String operationContent = "Prepare service : " + execution.getVariable("operationStatus")
309 logger.info( "Generated new operation for Service Instance serviceId:" + serviceId + " operationId:" + operationId)
310 serviceId = UriUtils.encode(serviceId,"UTF-8")
311 execution.setVariable("serviceInstanceId", serviceId)
312 execution.setVariable("operationId", operationId)
313 execution.setVariable("operationType", operationType)
315 def dbAdapterEndpoint = UrnPropertiesReader.getVariable("mso.adapters.openecomp.db.endpoint", execution)
316 execution.setVariable("CVFMI_dbAdapterEndpoint", dbAdapterEndpoint)
317 logger.info( "DB Adapter Endpoint is: " + dbAdapterEndpoint)
320 """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
321 xmlns:ns="http://org.onap.so/requestsdb">
324 <ns:updateServiceOperationStatus xmlns:ns="http://org.onap.so/requestsdb">
325 <serviceId>${MsoUtils.xmlEscape(serviceId)}</serviceId>
326 <operationId>${MsoUtils.xmlEscape(operationId)}</operationId>
327 <operationType>${MsoUtils.xmlEscape(operationType)}</operationType>
328 <userId>${MsoUtils.xmlEscape(userId)}</userId>
329 <result>${MsoUtils.xmlEscape(result)}</result>
330 <operationContent>${MsoUtils.xmlEscape(operationContent)}</operationContent>
331 <progress>${MsoUtils.xmlEscape(progress)}</progress>
332 <reason>${MsoUtils.xmlEscape(reason)}</reason>
333 </ns:updateServiceOperationStatus>
335 </soapenv:Envelope>"""
337 payload = utils.formatXml(payload)
338 execution.setVariable("CVFMI_updateServiceOperStatusRequest", payload)
339 logger.error( "Outgoing preUpdateServiceOperationStatus: \n" + payload)
343 logger.info( "Exception Occured Processing preUpdateServiceOperationStatus. Exception is:\n" + e)
344 execution.setVariable("CVFMI_ErrorResponse", "Error Occurred during preUpdateServiceOperationStatus Method:\n" + e.getMessage())
346 logger.info( "======== COMPLETED preUpdateServiceOperationStatus Process ======== ")
347 logger.info( "Exited " + method)
350 public void sendSyncResponse (DelegateExecution execution) {
351 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
352 logger.info( " *** sendSyncResponse *** ")
355 String operationId = execution.getVariable("operationId")
356 def hasResourcetoUpdate = execution.getVariable("hasResourcetoUpdate")
358 String updateServiceResp = ""
359 if(hasResourcetoUpdate) {
360 // RESTResponse for API Handler (APIH) Reply Task
361 updateServiceResp = """{"operationId":"${operationId}"}""".trim()
364 updateServiceResp = """{"OperationResult":"No Resource to Add or Delete or Service Instance not found in AAI."}"""
367 logger.info( " sendSyncResponse to APIH:" + "\n" + updateServiceResp)
368 sendWorkflowResponse(execution, 202, updateServiceResp)
369 execution.setVariable("sentSyncResponse", true)
371 } catch (Exception ex) {
372 String msg = "Exceptuion in sendSyncResponse:" + ex.getMessage()
374 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
376 logger.info(" ***** Exit sendSyncResopnse *****")
379 public void sendSyncError (DelegateExecution execution) {
380 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
381 logger.info( " *** sendSyncError *** ")
384 String errorMessage = ""
386 if (execution.getVariable("WorkflowException") instanceof WorkflowException) {
387 WorkflowException wfe = execution.getVariable("WorkflowException")
388 errorMessage = wfe.getErrorMessage()
389 errorCode = wfe.getErrorCode()
391 errorMessage = "Sending Sync Error."
394 String buildworkflowException =
395 """<aetgt:WorkflowException xmlns:aetgt="http://org.onap/so/workflow/schema/v1">
396 <aetgt:ErrorMessage>${MsoUtils.xmlEscape(errorMessage)}</aetgt:ErrorMessage>
397 <aetgt:ErrorCode>${MsoUtils.xmlEscape(errorCode)}</aetgt:ErrorCode>
398 </aetgt:WorkflowException>"""
400 sendWorkflowResponse(execution, 500, buildworkflowException)
402 } catch (Exception ex) {
403 logger.info( " Sending Sync Error Activity Failed. " + "\n" + ex.getMessage())
408 public void prepareCompletionRequest (DelegateExecution execution) {
409 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
410 logger.info( " *** prepareCompletion *** ")
413 String requestId = execution.getVariable("msoRequestId")
414 String serviceInstanceId = execution.getVariable("serviceInstanceId")
415 String source = execution.getVariable("source")
417 String msoCompletionRequest =
418 """<aetgt:MsoCompletionRequest xmlns:aetgt="http://org.onap/so/workflow/schema/v1"
419 xmlns:ns="http://org.onap/so/request/types/v1">
420 <request-info xmlns="http://org.onap/so/infra/vnf-request/v1">
421 <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
422 <action>UPDATE</action>
423 <source>${MsoUtils.xmlEscape(source)}</source>
425 <status-message>Service Instance was updated successfully.</status-message>
426 <serviceInstanceId>${MsoUtils.xmlEscape(serviceInstanceId)}</serviceInstanceId>
427 <mso-bpel-name>UpdateCustomE2EServiceInstance</mso-bpel-name>
428 </aetgt:MsoCompletionRequest>"""
431 String xmlMsoCompletionRequest = utils.formatXml(msoCompletionRequest)
433 execution.setVariable("completionRequest", xmlMsoCompletionRequest)
434 logger.info( " Overall SUCCESS Response going to CompleteMsoProcess - " + "\n" + xmlMsoCompletionRequest)
436 } catch (Exception ex) {
437 String msg = " Exception in prepareCompletion:" + ex.getMessage()
439 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
441 logger.info( "*** Exit prepareCompletionRequest ***")
444 public void prepareFalloutRequest(DelegateExecution execution){
445 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
446 logger.info( " *** prepareFalloutRequest *** ")
449 WorkflowException wfex = execution.getVariable("WorkflowException")
450 logger.info( " Input Workflow Exception: " + wfex.toString())
451 String requestId = execution.getVariable("msoRequestId")
452 String source = execution.getVariable("source")
454 """<request-info xmlns="http://org.onap/so/infra/vnf-request/v1">
455 <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
456 <action>UPDATE</action>
457 <source>${MsoUtils.xmlEscape(source)}</source>
460 String falloutRequest = exceptionUtil.processMainflowsBPMNException(execution, requestInfo)
461 execution.setVariable("falloutRequest", falloutRequest)
462 } catch (Exception ex) {
463 logger.info( "Exception prepareFalloutRequest:" + ex.getMessage())
464 String errorException = " Bpmn error encountered in UpdateCustomE2EServiceInstance flow. FalloutHandlerRequest, buildErrorResponse() - " + ex.getMessage()
465 String requestId = execution.getVariable("msoRequestId")
466 String falloutRequest =
467 """<aetgt:FalloutHandlerRequest xmlns:aetgt="http://org.onap/so/workflow/schema/v1"
468 xmlns:ns="http://org.onap/so/request/types/v1"
469 xmlns:wfsch="http://org.onap/so/workflow/schema/v1">
470 <request-info xmlns="http://org.onap/so/infra/vnf-request/v1">
471 <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
472 <action>UPDATE</action>
475 <aetgt:WorkflowException xmlns:aetgt="http://org.onap/so/workflow/schema/v1">
476 <aetgt:ErrorMessage>${MsoUtils.xmlEscape(errorException)}</aetgt:ErrorMessage>
477 <aetgt:ErrorCode>7000</aetgt:ErrorCode>
478 </aetgt:WorkflowException>
479 </aetgt:FalloutHandlerRequest>"""
481 execution.setVariable("falloutRequest", falloutRequest)
483 logger.info( "*** Exit prepareFalloutRequest ***")