1168b2022007d2b1831d16cb3f82e05d252e3cbb
[so.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
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
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
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=========================================================
21  */
22
23 package org.onap.so.bpmn.infrastructure.scripts;
24
25 import static org.apache.commons.lang3.StringUtils.*;
26
27 import javax.ws.rs.NotFoundException
28
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
50
51 import groovy.json.*
52
53 /**
54  * This groovy class supports the <class>UpdateCustomE2EServiceInstance.bpmn</class> process.
55  * AlaCarte flow for 1702 ServiceInstance Update
56  *
57  */
58 public class UpdateCustomE2EServiceInstance extends AbstractServiceTaskProcessor {
59         private static final Logger logger = LoggerFactory.getLogger( UpdateCustomE2EServiceInstance.class);
60
61         String Prefix="UPDSI_"
62         ExceptionUtil exceptionUtil = new ExceptionUtil()
63         JsonUtils jsonUtil = new JsonUtils()
64
65
66         public void preProcessRequest (DelegateExecution execution) {
67                 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
68                 execution.setVariable("prefix",Prefix)
69                 String msg = ""
70                 logger.info( " *** preProcessRequest() *** ")
71
72                 try {
73
74                         String siRequest = execution.getVariable("bpmnRequest")
75
76                         String requestId = execution.getVariable("mso-request-id")
77                         execution.setVariable("msoRequestId", requestId)
78                         logger.info( "Input Request:" + siRequest + " reqId:" + requestId)
79
80                         String serviceInstanceId = execution.getVariable("serviceInstanceId")
81                         if (isBlank(serviceInstanceId)) {
82                                 msg = "Input serviceInstanceId' is null"
83                                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
84                         }
85
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)
91                         } else {
92                                 execution.setVariable("globalSubscriberId", globalSubscriberId)
93                         }
94
95                         //requestDetails
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))
101                         {
102                                 msg = "Input productFamilyId is null"
103                                 logger.info( msg)
104                         } else {
105                                 execution.setVariable("productFamilyId", productFamilyId)
106                         }
107
108                          //user params
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"
115                                 logger.info( msg)
116                                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
117                         } else
118                         {
119                                 execution.setVariable("uuiRequest", uuiRequest)
120                         }
121
122                         logger.info( "uuiRequest:\n" + uuiRequest)
123
124                         //serviceType for aai
125                         String serviceType = jsonUtil.getJsonValue(uuiRequest, "service.serviceType")
126                         if (isBlank(serviceType)) {
127                                 msg = "Input serviceType is null"
128                                 logger.info( msg)
129                                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
130                         } else {
131                                 execution.setVariable("serviceType", serviceType)
132                         }
133
134                         // target model info
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)
139
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)
144
145                         String serviceModelName = jsonUtil.getJsonValue(uuiRequest, "service.parameters.templateName")
146                         logger.info("serviceModelName: " + serviceModelName)
147                         if(serviceModelName == null) {
148                                 serviceModelName = ""
149                         }
150                         execution.setVariable("serviceModelName", serviceModelName)
151
152                         //operationId
153                         String operationId = jsonUtil.getJsonValue(siRequest, "operationId")
154                         if (isBlank(operationId)) {
155                                 operationId = UUID.randomUUID().toString()
156                          }
157                         execution.setVariable("operationId", operationId)
158                         execution.setVariable("operationType", "update")
159                         execution.setVariable("hasResourcetoUpdate", false)
160
161                 } catch (BpmnError e) {
162                         throw e;
163                 } catch (Exception ex){
164                         msg = "Exception in preProcessRequest " + ex.getMessage()
165                         logger.info( msg)
166                         exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
167                 }
168                 logger.info(" ***** Exit preProcessRequest *****")
169         }
170
171         /**
172          * Gets the service instance and its relationships from aai
173          */
174         public void getServiceInstance(DelegateExecution execution) {
175                 try {
176                         String serviceInstanceId = execution.getVariable('serviceInstanceId')
177                         String globalSubscriberId = execution.getVariable('globalSubscriberId')
178                         String serviceType = execution.getVariable('serviceType')
179
180                         AAIResourcesClient resourceClient = new AAIResourcesClient()
181                         AAIResourceUri serviceInstanceUri = AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE, globalSubscriberId, serviceType, serviceInstanceId)
182                         AAIResultWrapper wrapper = resourceClient.get(serviceInstanceUri, NotFoundException.class)
183
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())
188
189                         JSONObject ob = new JSONObject(wrapper.getJson())
190                         JSONArray ar = ob.getJSONObject("relationship-list").getJSONArray("relationship")
191
192                         execution.setVariable("serviceRelationShip", ar.toString())
193
194
195                 }catch(BpmnError e) {
196                         throw 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)
202                 }
203         }
204
205         public void preCompareModelVersions(DelegateExecution execution) {
206                 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
207         }
208
209         public void postCompareModelVersions(DelegateExecution execution) {
210                 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
211                 logger.debug( " ======== STARTED postCompareModelVersions Process ======== ")
212
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")
218
219                 if(addResourceList != null && !addResourceList.isEmpty()) {
220                         hasResourcetoAdd = true
221                 }
222
223                 if(delResourceList != null && !delResourceList.isEmpty()) {
224                         hasResourcetoDelete = true
225                 }
226
227                 hasResourcetoUpdate = hasResourcetoAdd || hasResourcetoDelete
228                 execution.setVariable("hasResourcetoUpdate", hasResourcetoUpdate)
229
230                 logger.debug( "======== COMPLETED postCompareModelVersions Process ======== ")
231         }
232
233         /**
234          * Init the service Operation Status
235          */
236         public void prepareInitServiceOperationStatus(DelegateExecution execution){
237                 def isDebugEnabled = execution.getVariable("isDebugLogEnabled")
238                 logger.debug( " ======== STARTED prepareInitServiceOperationStatus Process ======== ")
239                 try{
240                         String serviceId = execution.getVariable("serviceInstanceId")
241                         String operationId = execution.getVariable("operationId")
242                         String operationType = execution.getVariable("operationType")
243                         String userId = ""
244                         String result = "processing"
245                         String progress = "0"
246                         String reason = ""
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)
253
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)
257
258                         String payload =
259                                 """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
260                         xmlns:ns="http://org.onap.so/requestsdb">
261                         <soapenv:Header/>
262                         <soapenv:Body>
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>
273                     </soapenv:Body>
274                 </soapenv:Envelope>"""
275
276                         payload = utils.formatXml(payload)
277                         execution.setVariable("CVFMI_updateServiceOperStatusRequest", payload)
278                         logger.error( "Outgoing updateServiceOperStatusRequest: \n" + payload)
279
280                 }catch(Exception e){
281                         logger.debug( "Exception Occured Processing prepareInitServiceOperationStatus. Exception is:\n" + e)
282                         execution.setVariable("CVFMI_ErrorResponse", "Error Occurred during prepareInitServiceOperationStatus Method:\n" + e.getMessage())
283                 }
284                 logger.debug( "======== COMPLETED prepareInitServiceOperationStatus Process ======== ")
285         }
286
287         /**
288          * Update the service Operation Status
289          */
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)
294
295                 try{
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")
303                         String userId = ""
304                         logger.info( "progress: " + progress )
305
306                         String operationContent = "Prepare service : " + execution.getVariable("operationStatus")
307
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)
313
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)
317
318                         String payload =
319                                 """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
320                         xmlns:ns="http://org.onap.so/requestsdb">
321                         <soapenv:Header/>
322                         <soapenv:Body>
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>
333                     </soapenv:Body>
334                 </soapenv:Envelope>"""
335
336                         payload = utils.formatXml(payload)
337                         execution.setVariable("CVFMI_updateServiceOperStatusRequest", payload)
338                         logger.error( "Outgoing preUpdateServiceOperationStatus: \n" + payload)
339
340
341                 }catch(Exception e){
342                         logger.info( "Exception Occured Processing preUpdateServiceOperationStatus. Exception is:\n" + e)
343                         execution.setVariable("CVFMI_ErrorResponse", "Error Occurred during preUpdateServiceOperationStatus Method:\n" + e.getMessage())
344                 }
345                 logger.info( "======== COMPLETED preUpdateServiceOperationStatus Process ======== ")
346                 logger.info( "Exited " + method)
347         }
348
349         public void sendSyncResponse (DelegateExecution execution) {
350                 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
351                 logger.info( " *** sendSyncResponse *** ")
352
353                 try {
354                         String operationId = execution.getVariable("operationId")
355                         def hasResourcetoUpdate = execution.getVariable("hasResourcetoUpdate")
356
357                         String updateServiceResp = ""
358                         if(hasResourcetoUpdate) {
359                                 // RESTResponse for API Handler (APIH) Reply Task
360                                 updateServiceResp = """{"operationId":"${operationId}"}""".trim()
361                         }
362                         else {
363                                 updateServiceResp =  """{"OperationResult":"No Resource to Add or Delete or Service Instance not found in AAI."}"""
364                         }
365
366                         logger.info( " sendSyncResponse to APIH:" + "\n" + updateServiceResp)
367                         sendWorkflowResponse(execution, 202, updateServiceResp)
368                         execution.setVariable("sentSyncResponse", true)
369
370                 } catch (Exception ex) {
371                         String msg = "Exceptuion in sendSyncResponse:" + ex.getMessage()
372                         logger.info( msg)
373                         exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
374                 }
375                 logger.info(" ***** Exit sendSyncResopnse *****")
376         }
377
378         public void sendSyncError (DelegateExecution execution) {
379                 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
380                 logger.info( " *** sendSyncError *** ")
381
382                 try {
383                         String errorMessage = ""
384                         int errorCode = 7000
385                         if (execution.getVariable("WorkflowException") instanceof WorkflowException) {
386                                 WorkflowException wfe = execution.getVariable("WorkflowException")
387                                 errorMessage = wfe.getErrorMessage()
388                                 errorCode = wfe.getErrorCode()
389                         } else {
390                                 errorMessage = "Sending Sync Error."
391                         }
392
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>"""
398
399                         sendWorkflowResponse(execution, 500, buildworkflowException)
400
401                 } catch (Exception ex) {
402                         logger.info( " Sending Sync Error Activity Failed. " + "\n" + ex.getMessage())
403                 }
404
405         }
406
407         public void prepareCompletionRequest (DelegateExecution execution) {
408                 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
409                 logger.info( " *** prepareCompletion *** ")
410
411                 try {
412                         String requestId = execution.getVariable("msoRequestId")
413                         String serviceInstanceId = execution.getVariable("serviceInstanceId")
414                         String source = execution.getVariable("source")
415
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>
423                                                 </request-info>
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>"""
428
429                         // Format Response
430                         String xmlMsoCompletionRequest = utils.formatXml(msoCompletionRequest)
431
432                         execution.setVariable("completionRequest", xmlMsoCompletionRequest)
433                         logger.info( " Overall SUCCESS Response going to CompleteMsoProcess - " + "\n" + xmlMsoCompletionRequest)
434
435                 } catch (Exception ex) {
436                         String msg = " Exception in prepareCompletion:" + ex.getMessage()
437                         logger.info( msg)
438                         exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
439                 }
440                 logger.info( "*** Exit prepareCompletionRequest ***")
441         }
442
443         public void prepareFalloutRequest(DelegateExecution execution){
444                 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
445                 logger.info( " *** prepareFalloutRequest *** ")
446
447                 try {
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")
452                         String requestInfo =
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>
457                                    </request-info>"""
458
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>
472                                               <source>UUI</source>
473                                            </request-info>
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>"""
479
480                         execution.setVariable("falloutRequest", falloutRequest)
481                 }
482                 logger.info( "*** Exit prepareFalloutRequest ***")
483         }
484 }