282e9611fd5ebc4520457ac7b8df28b0aa70edfc
[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.aaiclient.client.aai.AAIObjectType
43 import org.onap.aaiclient.client.aai.AAIResourcesClient
44 import org.onap.aaiclient.client.aai.entities.AAIResultWrapper
45 import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri
46 import org.onap.aaiclient.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("serviceInstanceData-original", si.get())
193                         execution.setVariable("serviceRelationShip", ar.toString())
194
195
196                 }catch(BpmnError e) {
197                         throw 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)
203                 }
204         }
205
206         public void preCompareModelVersions(DelegateExecution execution) {
207                 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
208         }
209
210         public void postCompareModelVersions(DelegateExecution execution) {
211                 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
212                 logger.debug( " ======== STARTED postCompareModelVersions Process ======== ")
213
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")
219
220                 if(addResourceList != null && !addResourceList.isEmpty()) {
221                         hasResourcetoAdd = true
222                 }
223
224                 if(delResourceList != null && !delResourceList.isEmpty()) {
225                         hasResourcetoDelete = true
226                 }
227
228                 hasResourcetoUpdate = hasResourcetoAdd || hasResourcetoDelete
229                 execution.setVariable("hasResourcetoUpdate", hasResourcetoUpdate)
230
231                 logger.debug( "======== COMPLETED postCompareModelVersions Process ======== ")
232         }
233
234         /**
235          * Init the service Operation Status
236          */
237         public void prepareInitServiceOperationStatus(DelegateExecution execution){
238                 def isDebugEnabled = execution.getVariable("isDebugLogEnabled")
239                 logger.debug( " ======== STARTED prepareInitServiceOperationStatus Process ======== ")
240                 try{
241                         String serviceId = execution.getVariable("serviceInstanceId")
242                         String operationId = execution.getVariable("operationId")
243                         String operationType = execution.getVariable("operationType")
244                         String userId = ""
245                         String result = "processing"
246                         String progress = "0"
247                         String reason = ""
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)
254
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)
258
259                         String payload =
260                                 """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
261                         xmlns:ns="http://org.onap.so/requestsdb">
262                         <soapenv:Header/>
263                         <soapenv:Body>
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>
274                     </soapenv:Body>
275                 </soapenv:Envelope>"""
276
277                         payload = utils.formatXml(payload)
278                         execution.setVariable("CVFMI_updateServiceOperStatusRequest", payload)
279                         logger.error( "Outgoing updateServiceOperStatusRequest: \n" + payload)
280
281                 }catch(Exception e){
282                         logger.debug( "Exception Occured Processing prepareInitServiceOperationStatus. Exception is:\n" + e)
283                         execution.setVariable("CVFMI_ErrorResponse", "Error Occurred during prepareInitServiceOperationStatus Method:\n" + e.getMessage())
284                 }
285                 logger.debug( "======== COMPLETED prepareInitServiceOperationStatus Process ======== ")
286         }
287
288         /**
289          * Update the service Operation Status
290          */
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)
295
296                 try{
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")
304                         String userId = ""
305                         logger.info( "progress: " + progress )
306
307                         String operationContent = "Prepare service : " + execution.getVariable("operationStatus")
308
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)
314
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)
318
319                         String payload =
320                                 """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
321                         xmlns:ns="http://org.onap.so/requestsdb">
322                         <soapenv:Header/>
323                         <soapenv:Body>
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>
334                     </soapenv:Body>
335                 </soapenv:Envelope>"""
336
337                         payload = utils.formatXml(payload)
338                         execution.setVariable("CVFMI_updateServiceOperStatusRequest", payload)
339                         logger.error( "Outgoing preUpdateServiceOperationStatus: \n" + payload)
340
341
342                 }catch(Exception e){
343                         logger.info( "Exception Occured Processing preUpdateServiceOperationStatus. Exception is:\n" + e)
344                         execution.setVariable("CVFMI_ErrorResponse", "Error Occurred during preUpdateServiceOperationStatus Method:\n" + e.getMessage())
345                 }
346                 logger.info( "======== COMPLETED preUpdateServiceOperationStatus Process ======== ")
347                 logger.info( "Exited " + method)
348         }
349
350         public void sendSyncResponse (DelegateExecution execution) {
351                 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
352                 logger.info( " *** sendSyncResponse *** ")
353
354                 try {
355                         String operationId = execution.getVariable("operationId")
356                         def hasResourcetoUpdate = execution.getVariable("hasResourcetoUpdate")
357
358                         String updateServiceResp = ""
359                         if(hasResourcetoUpdate) {
360                                 // RESTResponse for API Handler (APIH) Reply Task
361                                 updateServiceResp = """{"operationId":"${operationId}"}""".trim()
362                         }
363                         else {
364                                 updateServiceResp =  """{"OperationResult":"No Resource to Add or Delete or Service Instance not found in AAI."}"""
365                         }
366
367                         logger.info( " sendSyncResponse to APIH:" + "\n" + updateServiceResp)
368                         sendWorkflowResponse(execution, 202, updateServiceResp)
369                         execution.setVariable("sentSyncResponse", true)
370
371                 } catch (Exception ex) {
372                         String msg = "Exceptuion in sendSyncResponse:" + ex.getMessage()
373                         logger.info( msg)
374                         exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
375                 }
376                 logger.info(" ***** Exit sendSyncResopnse *****")
377         }
378
379         public void sendSyncError (DelegateExecution execution) {
380                 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
381                 logger.info( " *** sendSyncError *** ")
382
383                 try {
384                         String errorMessage = ""
385                         int errorCode = 7000
386                         if (execution.getVariable("WorkflowException") instanceof WorkflowException) {
387                                 WorkflowException wfe = execution.getVariable("WorkflowException")
388                                 errorMessage = wfe.getErrorMessage()
389                                 errorCode = wfe.getErrorCode()
390                         } else {
391                                 errorMessage = "Sending Sync Error."
392                         }
393
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>"""
399
400                         sendWorkflowResponse(execution, 500, buildworkflowException)
401
402                 } catch (Exception ex) {
403                         logger.info( " Sending Sync Error Activity Failed. " + "\n" + ex.getMessage())
404                 }
405
406         }
407
408         public void prepareCompletionRequest (DelegateExecution execution) {
409                 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
410                 logger.info( " *** prepareCompletion *** ")
411
412                 try {
413                         String requestId = execution.getVariable("msoRequestId")
414                         String serviceInstanceId = execution.getVariable("serviceInstanceId")
415                         String source = execution.getVariable("source")
416
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>
424                                                 </request-info>
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>"""
429
430                         // Format Response
431                         String xmlMsoCompletionRequest = utils.formatXml(msoCompletionRequest)
432
433                         execution.setVariable("completionRequest", xmlMsoCompletionRequest)
434                         logger.info( " Overall SUCCESS Response going to CompleteMsoProcess - " + "\n" + xmlMsoCompletionRequest)
435
436                 } catch (Exception ex) {
437                         String msg = " Exception in prepareCompletion:" + ex.getMessage()
438                         logger.info( msg)
439                         exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
440                 }
441                 logger.info( "*** Exit prepareCompletionRequest ***")
442         }
443
444         public void prepareFalloutRequest(DelegateExecution execution){
445                 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
446                 logger.info( " *** prepareFalloutRequest *** ")
447
448                 try {
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")
453                         String requestInfo =
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>
458                                    </request-info>"""
459
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>
473                                               <source>UUI</source>
474                                            </request-info>
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>"""
480
481                         execution.setVariable("falloutRequest", falloutRequest)
482                 }
483                 logger.info( "*** Exit prepareFalloutRequest ***")
484         }
485 }