Fix DeleteSliceService auth
[so.git] / bpmn / so-bpmn-infrastructure-common / src / main / groovy / org / onap / so / bpmn / infrastructure / scripts / DeleteCommunicationService.groovy
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  # Copyright (c) 2019, CMCC Technologies Co., Ltd.
6  #
7  # Licensed under the Apache License, Version 2.0 (the "License")
8  # you may not use this file except in compliance with the License.
9  # You may obtain a copy of the License at
10  #
11  #       http://www.apache.org/licenses/LICENSE-2.0
12  #
13  # Unless required by applicable law or agreed to in writing, software
14  # distributed under the License is distributed on an "AS IS" BASIS,
15  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  # See the License for the specific language governing permissions and
17  # limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20 package org.onap.so.bpmn.infrastructure.scripts
21
22 import org.onap.aaiclient.client.aai.entities.uri.AAISimpleUri
23
24 import static org.apache.commons.lang3.StringUtils.isBlank
25 import javax.ws.rs.NotFoundException
26 import javax.ws.rs.core.Response
27 import org.camunda.bpm.engine.delegate.BpmnError
28 import org.camunda.bpm.engine.delegate.DelegateExecution
29 import org.onap.aai.domain.yang.CommunicationServiceProfile
30 import org.onap.aai.domain.yang.CommunicationServiceProfiles
31 import org.onap.aai.domain.yang.Relationship
32 import org.onap.aai.domain.yang.ServiceInstance
33 import org.onap.aaiclient.client.aai.AAIObjectName
34 import org.onap.aaiclient.client.aai.AAIObjectType
35 import org.onap.aaiclient.client.aai.entities.AAIResultWrapper
36 import org.onap.aaiclient.client.aai.entities.uri.AAIPluralResourceUri
37 import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri
38 import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory
39 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder
40 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder.Types
41 import org.onap.logging.filter.base.ONAPComponents
42 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor
43 import org.onap.so.bpmn.common.scripts.ExceptionUtil
44 import org.onap.so.bpmn.common.scripts.MsoUtils
45 import org.onap.so.bpmn.common.scripts.RequestDBUtil
46 import org.onap.so.bpmn.core.UrnPropertiesReader
47 import org.onap.so.bpmn.core.WorkflowException
48 import org.onap.so.bpmn.core.json.JsonUtils
49 import org.onap.so.client.HttpClient
50 import org.onap.so.db.request.beans.OperationStatus
51 import org.slf4j.Logger
52 import org.slf4j.LoggerFactory
53
54 class DeleteCommunicationService extends AbstractServiceTaskProcessor {
55     private final String PREFIX ="DeleteCommunicationService"
56     private final Long TIMEOUT = 60 * 60 * 1000
57
58     ExceptionUtil exceptionUtil = new ExceptionUtil()
59     JsonUtils jsonUtil = new JsonUtils()
60     private RequestDBUtil requestDBUtil = new RequestDBUtil()
61     private static final Logger LOGGER = LoggerFactory.getLogger(DeleteCommunicationService.class)
62
63     @Override
64     void preProcessRequest(DelegateExecution execution) {
65         execution.setVariable("prefix",PREFIX)
66         String msg = ""
67
68         LOGGER.trace("Starting preProcessRequest")
69
70         try {
71             // check for incoming json message/input
72             String siRequest = execution.getVariable("bpmnRequest")
73             String requestId = execution.getVariable("mso-request-id")
74             execution.setVariable("msoRequestId", requestId)
75             execution.setVariable("operationType", "DELETE")
76
77             //communication service id
78             String serviceInstanceId = execution.getVariable("serviceInstanceId")
79             if (isBlank(serviceInstanceId)) {
80                 msg = "communication-service id is null"
81                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
82             }
83
84             LOGGER.info("Input Request: ${siRequest}, reqId: ${requestId}, serviceInstanceId: ${serviceInstanceId}")
85
86             //requestParameters
87             checkAndSetRequestParam(siRequest,"globalSubscriberId",false,execution)
88             checkAndSetRequestParam(siRequest,"serviceType",false,execution)
89             checkAndSetRequestParam(siRequest,"operationId",false,execution)
90
91         } catch (BpmnError e) {
92             throw e
93         } catch (any) {
94             msg = "Exception in preProcessRequest " + any.getCause()
95             LOGGER.debug(msg)
96             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
97         }
98         LOGGER.trace("Exit preProcessRequest")
99     }
100
101
102     /**
103      * prepare update operation status
104      * @param execution
105      */
106     void preInitUpdateOperationStatus(DelegateExecution execution){
107         LOGGER.trace(" ======== STARTED initUpdateOperationStatus Process ======== ")
108         try{
109             execution.setVariable("result","processing")
110             execution.setVariable("progress","0")
111             execution.setVariable("operationContent","delete communication service operation start")
112             setOperationStatus(execution)
113
114         }catch(Exception e){
115             LOGGER.error("Exception Occured Processing initUpdateOperationStatus. Exception is:\n" + e)
116             execution.setVariable("CVFMI_ErrorResponse", "Error Occurred during initUpdateOperationStatus Method:\n" + e.getMessage())
117         }
118         LOGGER.trace("======== COMPLETED initUpdateOperationStatus Process ======== ")
119     }
120
121     /**
122      * send sync response
123      * @param execution
124      */
125     void sendSyncResponse(DelegateExecution execution) {
126         LOGGER.debug("Begin sendSyncResponse")
127
128         try {
129             String operationId = execution.getVariable("operationId")
130             String syncResponse = """{"operationId":"${operationId}"}""".trim()
131             sendWorkflowResponse(execution, 202, syncResponse)
132
133         } catch (Exception ex) {
134             String msg  = "Exception in sendSyncResponse: " + ex.getMessage()
135             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
136         }
137         LOGGER.debug("Exit sendSyncResponse")
138     }
139
140     /**
141      * query CommunicationSerive from AAI
142      * save e2eslice-service instance id and service name
143      * @param execution
144      */
145     void queryCommunicationSeriveFromAAI(DelegateExecution execution)
146     {
147         LOGGER.trace(" ***** begin queryCommunicationSeriveFromAAI *****")
148         String serviceInstanceId = execution.getVariable("serviceInstanceId")
149
150         String errorMsg = "query communication service from aai failed"
151         AAIResultWrapper wrapper = queryAAI(execution, Types.SERVICE_INSTANCE, serviceInstanceId, errorMsg)
152         Optional<ServiceInstance> si = wrapper.asBean(ServiceInstance.class)
153         if(si.isPresent())
154         {
155             String serviceInstName = si.get()?.getServiceInstanceName()
156             String e2eSliceServiceInstId
157             if(si.isPresent())
158             {
159                 List<Relationship> relationshipList = si.get().getRelationshipList()?.getRelationship()
160                 for (Relationship relationship : relationshipList)
161                 {
162                     String relatedTo = relationship.getRelatedTo()
163                     if (relatedTo == "service-instance")
164                     {
165                         String relatedLink = relationship.getRelatedLink()?:""
166                         e2eSliceServiceInstId = relatedLink ? relatedLink.substring(relatedLink.lastIndexOf("/") + 1,relatedLink.length()) : ""
167                         break
168                     }
169                 }
170             }
171             execution.setVariable("e2eSliceServiceInstanceId", e2eSliceServiceInstId)
172             execution.setVariable("serviceInstanceName", serviceInstName ?: "")
173             LOGGER.info("communication-service Id: ${serviceInstanceId}, e2eslice-service Id: ${e2eSliceServiceInstId}, serviceName: ${serviceInstName}")
174         }
175         LOGGER.debug(" ***** Exit queryCommunicationSeriveFromAAI *****")
176     }
177
178     /**
179      * query AAI
180      * @param execution
181      * @param aaiObjectName
182      * @param instanceId
183      * @return AAIResultWrapper
184      */
185     private AAIResultWrapper queryAAI(DelegateExecution execution, AAIObjectName aaiObjectName, String instanceId, String errorMsg)
186     {
187         String globalSubscriberId = execution.getVariable("globalSubscriberId")
188         String serviceType = execution.getVariable("serviceType")
189
190         AAIResourceUri resourceUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(globalSubscriberId).serviceSubscription(serviceType).serviceInstance(instanceId))
191         if (!getAAIClient().exists(resourceUri)) {
192             exceptionUtil.buildAndThrowWorkflowException(execution, 2500, errorMsg)
193         }
194         AAIResultWrapper wrapper = getAAIClient().get(resourceUri, NotFoundException.class)
195         return wrapper
196     }
197
198
199     /**
200      * 再次调用deleteE2EServiceInstance接口,然后获取到operationid,
201      */
202     void sendRequest2NSMFWF(DelegateExecution execution) {
203         LOGGER.debug("begin preRequestSend2NSMF")
204         try {
205             //url:/onap/so/infra/e2eServiceInstances/v3/{serviceInstanceId}"
206             def NSMF_endpoint = UrnPropertiesReader.getVariable("mso.infra.endpoint.url", execution)
207             String url = "${NSMF_endpoint}/e2eServiceInstances/v3/${execution.getVariable("e2eSliceServiceInstanceId")}"
208
209             String requestBody = """
210                 {
211                     "globalSubscriberId": "${execution.getVariable("globalSubscriberId")}",
212                     "serviceType": "${execution.getVariable("serviceType")}"
213                 }
214             """
215             requestBody.replaceAll("\\s+", "")
216
217             String msoKey = UrnPropertiesReader.getVariable("mso.msoKey", execution)
218             String basicAuth =  UrnPropertiesReader.getVariable("mso.adapters.po.auth", execution)
219             def authHeader = utils.getBasicAuth(basicAuth, msoKey)
220
221 //            String basicAuthValue = utils.encrypt(basicAuth, msoKey)
222 //            String encodeString = utils.getBasicAuth(basicAuthValue, msoKey)
223
224             HttpClient httpClient = getHttpClientFactory().newJsonClient(new URL(url), ONAPComponents.SO)
225 //            httpClient.addAdditionalHeader("Authorization", encodeString)
226             httpClient.addAdditionalHeader("Authorization", authHeader)
227             httpClient.addAdditionalHeader("Accept", "application/json")
228             Response httpResponse = httpClient.delete(requestBody)
229             handleNSSMFWFResponse(httpResponse, execution)
230
231         } catch (BpmnError e) {
232             throw e
233         } catch (any) {
234             String msg = "Exception in DeleteCommunicationService.preRequestSend2NSMF. " + any.getCause()
235             LOGGER.error(msg)
236             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
237         }
238
239         LOGGER.debug("exit preRequestSend2NSMF")
240     }
241
242     /**
243      * prepare update operation status
244      * @param execution
245      */
246     private void handleNSSMFWFResponse(Response httpResponse, DelegateExecution execution){
247         LOGGER.debug(" ======== STARTED prepareUpdateOperationStatus Process ======== ")
248
249         int nsmfResponseCode = httpResponse.getStatus()
250         LOGGER.debug("nsmfResponseCode${nsmfResponseCode}")
251
252         if (nsmfResponseCode >= 200 && nsmfResponseCode < 204 && httpResponse.hasEntity()) {
253             String nsmfResponse = httpResponse.readEntity(String.class)
254             def e2eOperationId = jsonUtil.getJsonValue(nsmfResponse, "operationId")
255             execution.setVariable("e2eOperationId", e2eOperationId)
256             execution.setVariable("progress","20")
257             execution.setVariable("operationContent","waiting nsmf service delete finished")
258
259             execution.setVariable("currentCycle",0)
260             execution.setVariable("isNSMFTimeOut", "no")
261             execution.setVariable("isNSMFWFRspSucceed","yes")
262         }
263         else
264         {
265             String serviceName = execution.getVariable("serviceInstanceName")
266             execution.setVariable("progress", "100")
267             execution.setVariable("result", "error")
268             execution.setVariable("operationContent", "terminate service failure.")
269             execution.setVariable("reason","NSMF WF asynchronous response failed, status Code:${nsmfResponseCode}")
270             execution.setVariable("isNSMFWFRspSucceed","no")
271             LOGGER.error("nsmf async response error,nsmfResponseCode:${nsmfResponseCode},serivceName:${serviceName}")
272         }
273         setOperationStatus(execution)
274         LOGGER.debug("======== COMPLETED prepareUpdateOperationStatus Process ======== ")
275     }
276
277     /**
278      * prepare to call sub process
279      * @param execution
280      */
281     void prepareCallCheckProcessStatus(DelegateExecution execution)
282     {
283         LOGGER.debug(PREFIX + "prepareCallCheckProcessStatus Start")
284
285         def successConditions = new ArrayList<>()
286         successConditions.add("finished")
287         execution.setVariable("successConditions", successConditions)
288
289         def errorConditions = new ArrayList<>()
290         errorConditions.add("error")
291         execution.setVariable("errorConditions", errorConditions)
292
293         execution.setVariable("processServiceType", "communication service")
294         execution.setVariable("subOperationType", "DELETE")
295         execution.setVariable("initProgress", 20)
296         execution.setVariable("endProgress",90)
297
298         execution.setVariable("timeOut", TIMEOUT)
299
300         LOGGER.debug(PREFIX + "prepareCallCheckProcessStatus Exit")
301     }
302
303     /**
304      * delete communication profile from AAI
305      * @param execution
306      */
307     void delCSProfileFromAAI(DelegateExecution execution)
308     {
309         LOGGER.debug("start delete communication service profile from AAI")
310         String globalSubscriberId = execution.getVariable("globalSubscriberId")
311         String serviceType = execution.getVariable("serviceType")
312         String serviceInstanceId = execution.getVariable("serviceInstanceId")
313
314         String profileId
315         try
316         {
317             AAIPluralResourceUri resourceUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(globalSubscriberId).serviceSubscription(serviceType).serviceInstance(serviceInstanceId).communicationServiceProfiles())
318             AAIResultWrapper wrapper = getAAIClient().get(resourceUri, NotFoundException.class)
319             Optional<CommunicationServiceProfiles> csProfilesOpt = wrapper.asBean(CommunicationServiceProfiles.class)
320             if(csProfilesOpt.isPresent()){
321                 CommunicationServiceProfiles csProfiles = csProfilesOpt.get()
322                 CommunicationServiceProfile csProfile = csProfiles.getCommunicationServiceProfile().get(0)
323                 profileId = csProfile ? csProfile.getProfileId() : ""
324             }
325             AAISimpleUri profileUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(globalSubscriberId).serviceSubscription(serviceType).serviceInstance(serviceInstanceId).communicationServiceProfile(profileId))
326             if (!getAAIClient().exists(profileUri)) {
327                 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "communication service profile was not found in aai")
328             }
329
330             getAAIClient().delete(profileUri)
331             LOGGER.debug("end delete communication service profile from AAI")
332         }
333         catch (any)
334         {
335             String msg = "delete communication service profile from aai failed! cause-"+any.getCause()
336             LOGGER.error(any.printStackTrace())
337             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg);
338         }
339
340     }
341
342     /**
343      * delete communication service from AAI
344      * @param execution
345      */
346     void delCSFromAAI(DelegateExecution execution)
347     {
348         try
349         {
350             LOGGER.debug("start delete communication service from AAI")
351             AAIResourceUri serviceInstanceUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(execution.getVariable("globalSubscriberId")).serviceSubscription(execution.getVariable("serviceType")).serviceInstance(execution.getVariable("serviceInstanceId")))
352             getAAIClient().delete(serviceInstanceUri)
353
354             execution.setVariable("progress", "100")
355             execution.setVariable("result", "finished")
356             execution.setVariable("operationContent", "CSMF completes service terminated.")
357             setOperationStatus(execution)
358             LOGGER.debug("end delete communication service from AAI")
359         }
360         catch (any)
361         {
362             LOGGER.error("Error occured within delCSFromAAI method, cause: ${any.getCause()} ")
363             exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Error occured during delete communication service from aai")
364         }
365     }
366
367     void sendSyncError(DelegateExecution execution)
368     {
369         LOGGER.debug("Starting sendSyncError")
370
371         try {
372             String errorMessage = "Sending Sync Error."
373             if (execution.getVariable("WorkflowException") instanceof WorkflowException) {
374                 WorkflowException wfe = execution.getVariable("WorkflowException")
375                 errorMessage = wfe.getErrorMessage()
376             }
377
378             String buildworkflowException =
379                     """<aetgt:WorkflowException xmlns:aetgt="http://org.onap/so/workflow/schema/v1">
380                                         <aetgt:ErrorMessage>${MsoUtils.xmlEscape(errorMessage)}</aetgt:ErrorMessage>
381                                         <aetgt:ErrorCode>7000</aetgt:ErrorCode>
382                                    </aetgt:WorkflowException>"""
383
384             LOGGER.debug(buildworkflowException)
385             sendWorkflowResponse(execution, 500, buildworkflowException)
386
387         } catch (Exception ex) {
388             LOGGER.error("Sending Sync Error Activity Failed. " + "\n" + ex.getMessage())
389         }
390     }
391
392     /**
393      * prepare update operation status
394      * @param execution
395      */
396     void preFailedOperationStatus(DelegateExecution execution)
397     {
398         LOGGER.debug(" ======== STARTED preFailedOperationStatus Process ======== ")
399
400         execution.setVariable("progress", "100")
401         execution.setVariable("result", "error")
402         execution.setVariable("operationContent", "terminate service failure")
403
404         WorkflowException wfex = execution.getVariable("WorkflowException") as WorkflowException
405         String errorMessage = wfex.getErrorMessage()
406         errorMessage = errorMessage.length() > 200 ? errorMessage.substring(0,200) + "......" : errorMessage
407         execution.setVariable("reason", errorMessage)
408         setOperationStatus(execution)
409
410         LOGGER.debug("======== COMPLETED prepareEndOperationStatus Process ======== ")
411     }
412
413     /**
414      * prepare Operation status
415      * @param execution
416      * @param operationType
417      */
418     private void setOperationStatus(DelegateExecution execution)
419     {
420         OperationStatus operationStatus = new OperationStatus()
421         operationStatus.setServiceId(execution.getVariable("serviceInstanceId"))
422         operationStatus.setOperationId(execution.getVariable("operationId"))
423         operationStatus.setUserId(execution.getVariable("globalSubscriberId"))
424         //interface not support update
425         operationStatus.setServiceName(execution.getVariable("serviceInstanceName"))
426         operationStatus.setResult(execution.getVariable("result"))
427         operationStatus.setProgress(execution.getVariable("progress"))
428         operationStatus.setOperationContent(execution.getVariable("operationContent"))
429         operationStatus.setReason(execution.getVariable("reason")?:"")
430         operationStatus.setOperation("DELETE")
431
432         requestDBUtil.prepareUpdateOperationStatus(execution, operationStatus)
433     }
434
435     void prepareFailureStatus(DelegateExecution execution)
436     {
437         execution.setVariable("result", "finished")
438         execution.setVariable("progress", "100")
439         execution.setVariable("operationContent", "terminate service failure.")
440         setOperationStatus(execution)
441         LOGGER.debug("${PREFIX}-prepareFailureStatus,result:${execution.getVariable("result")}, reason: ${execution.getVariable("reason")}")
442     }
443
444     /**
445      * check request json and save parameter to execution
446      * @param siRequest
447      * @param paraName
448      * @param isErrorException
449      * @param execution
450      */
451     private void checkAndSetRequestParam(String siRequest, String paraName, boolean isErrorException, DelegateExecution execution)
452     {
453         String msg = ""
454         String paramValue = jsonUtil.getJsonValue(siRequest, paraName)
455         if (isBlank(paramValue)) {
456             msg = "Input ${paraName} is null"
457             LOGGER.error(msg)
458             if(isErrorException)
459             {
460                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
461             }
462
463         } else {
464             execution.setVariable(paraName, paramValue)
465         }
466     }
467
468 }