8e554e286d6f7b147840600a85f341ebb8b8937d
[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("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 }