2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 # Copyright (c) 2019, CMCC Technologies Co., Ltd.
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
11 # http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
20 package org.onap.so.bpmn.infrastructure.scripts
23 import static org.apache.commons.lang3.StringUtils.isBlank
24 import javax.ws.rs.NotFoundException
25 import javax.ws.rs.core.Response
26 import org.camunda.bpm.engine.delegate.BpmnError
27 import org.camunda.bpm.engine.delegate.DelegateExecution
28 import org.onap.aai.domain.yang.CommunicationServiceProfile
29 import org.onap.aai.domain.yang.CommunicationServiceProfiles
30 import org.onap.aai.domain.yang.Relationship
31 import org.onap.aai.domain.yang.ServiceInstance
32 import org.onap.aaiclient.client.aai.AAIObjectName
33 import org.onap.aaiclient.client.aai.AAIObjectType
34 import org.onap.aaiclient.client.aai.entities.AAIResultWrapper
35 import org.onap.aaiclient.client.aai.entities.uri.AAIPluralResourceUri
36 import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri
37 import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory
38 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder
39 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder.Types
40 import org.onap.logging.filter.base.ONAPComponents
41 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor
42 import org.onap.so.bpmn.common.scripts.ExceptionUtil
43 import org.onap.so.bpmn.common.scripts.MsoUtils
44 import org.onap.so.bpmn.common.scripts.RequestDBUtil
45 import org.onap.so.bpmn.core.UrnPropertiesReader
46 import org.onap.so.bpmn.core.WorkflowException
47 import org.onap.so.bpmn.core.json.JsonUtils
48 import org.onap.so.client.HttpClient
49 import org.onap.so.db.request.beans.OperationStatus
50 import org.slf4j.Logger
51 import org.slf4j.LoggerFactory
53 class DeleteCommunicationService extends AbstractServiceTaskProcessor {
54 private final String PREFIX ="DeleteCommunicationService"
55 private final Long TIMEOUT = 60 * 60 * 1000
57 ExceptionUtil exceptionUtil = new ExceptionUtil()
58 JsonUtils jsonUtil = new JsonUtils()
59 private RequestDBUtil requestDBUtil = new RequestDBUtil()
60 private static final Logger LOGGER = LoggerFactory.getLogger(DeleteCommunicationService.class)
63 void preProcessRequest(DelegateExecution execution) {
64 execution.setVariable("prefix",PREFIX)
67 LOGGER.trace("Starting preProcessRequest")
70 // check for incoming json message/input
71 String siRequest = execution.getVariable("bpmnRequest")
72 String requestId = execution.getVariable("mso-request-id")
73 execution.setVariable("msoRequestId", requestId)
74 execution.setVariable("operationType", "DELETE")
76 //communication service id
77 String serviceInstanceId = execution.getVariable("serviceInstanceId")
78 if (isBlank(serviceInstanceId)) {
79 msg = "communication-service id is null"
80 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
83 LOGGER.info("Input Request: ${siRequest}, reqId: ${requestId}, serviceInstanceId: ${serviceInstanceId}")
86 checkAndSetRequestParam(siRequest,"globalSubscriberId",false,execution)
87 checkAndSetRequestParam(siRequest,"serviceType",false,execution)
88 checkAndSetRequestParam(siRequest,"operationId",false,execution)
90 } catch (BpmnError e) {
93 msg = "Exception in preProcessRequest " + any.getCause()
95 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
97 LOGGER.trace("Exit preProcessRequest")
102 * prepare update operation status
105 void preInitUpdateOperationStatus(DelegateExecution execution){
106 LOGGER.trace(" ======== STARTED initUpdateOperationStatus Process ======== ")
108 execution.setVariable("result","processing")
109 execution.setVariable("progress","0")
110 execution.setVariable("operationContent","delete communication service operation start")
111 setOperationStatus(execution)
114 LOGGER.error("Exception Occured Processing initUpdateOperationStatus. Exception is:\n" + e)
115 execution.setVariable("CVFMI_ErrorResponse", "Error Occurred during initUpdateOperationStatus Method:\n" + e.getMessage())
117 LOGGER.trace("======== COMPLETED initUpdateOperationStatus Process ======== ")
124 void sendSyncResponse(DelegateExecution execution) {
125 LOGGER.debug("Begin sendSyncResponse")
128 String operationId = execution.getVariable("operationId")
129 String syncResponse = """{"operationId":"${operationId}"}""".trim()
130 sendWorkflowResponse(execution, 202, syncResponse)
132 } catch (Exception ex) {
133 String msg = "Exception in sendSyncResponse: " + ex.getMessage()
134 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
136 LOGGER.debug("Exit sendSyncResponse")
140 * query CommunicationSerive from AAI
141 * save e2eslice-service instance id and service name
144 void queryCommunicationSeriveFromAAI(DelegateExecution execution)
146 LOGGER.trace(" ***** begin queryCommunicationSeriveFromAAI *****")
147 String serviceInstanceId = execution.getVariable("serviceInstanceId")
149 String errorMsg = "query communication service from aai failed"
150 AAIResultWrapper wrapper = queryAAI(execution, Types.SERVICE_INSTANCE, serviceInstanceId, errorMsg)
151 Optional<ServiceInstance> si = wrapper.asBean(ServiceInstance.class)
154 String serviceInstName = si.get()?.getServiceInstanceName()
155 String e2eSliceServiceInstId
158 List<Relationship> relationshipList = si.get().getRelationshipList()?.getRelationship()
159 for (Relationship relationship : relationshipList)
161 String relatedTo = relationship.getRelatedTo()
162 if (relatedTo == "service-instance")
164 String relatedLink = relationship.getRelatedLink()?:""
165 e2eSliceServiceInstId = relatedLink ? relatedLink.substring(relatedLink.lastIndexOf("/") + 1,relatedLink.length()) : ""
170 execution.setVariable("e2eSliceServiceInstanceId", e2eSliceServiceInstId)
171 execution.setVariable("serviceInstanceName", serviceInstName ?: "")
172 LOGGER.info("communication-service Id: ${serviceInstanceId}, e2eslice-service Id: ${e2eSliceServiceInstId}, serviceName: ${serviceInstName}")
174 LOGGER.debug(" ***** Exit queryCommunicationSeriveFromAAI *****")
180 * @param aaiObjectName
182 * @return AAIResultWrapper
184 private AAIResultWrapper queryAAI(DelegateExecution execution, AAIObjectName aaiObjectName, String instanceId, String errorMsg)
186 String globalSubscriberId = execution.getVariable("globalSubscriberId")
187 String serviceType = execution.getVariable("serviceType")
189 AAIResourceUri resourceUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(globalSubscriberId).serviceSubscription(serviceType).serviceInstance(instanceId))
190 if (!getAAIClient().exists(resourceUri)) {
191 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, errorMsg)
193 AAIResultWrapper wrapper = getAAIClient().get(resourceUri, NotFoundException.class)
199 * 再次调用deleteE2EServiceInstance接口,然后获取到operationid,
201 void sendRequest2NSMFWF(DelegateExecution execution) {
202 LOGGER.debug("begin preRequestSend2NSMF")
204 //url:/onap/so/infra/e2eServiceInstances/v3/{serviceInstanceId}"
205 def NSMF_endpoint = UrnPropertiesReader.getVariable("mso.infra.endpoint.url", execution)
206 String url = "${NSMF_endpoint}/e2eServiceInstances/v3/${execution.getVariable("e2eSliceServiceInstanceId")}"
208 String requestBody = """
210 "globalSubscriberId": "${execution.getVariable("globalSubscriberId")}",
211 "serviceType": "${execution.getVariable("serviceType")}"
214 requestBody.replaceAll("\\s+", "")
216 String msoKey = UrnPropertiesReader.getVariable("mso.msoKey", execution)
217 String basicAuth = UrnPropertiesReader.getVariable("mso.infra.endpoint.auth", execution)
218 // String basicAuthValue = utils.encrypt(basicAuth, msoKey)
219 // String encodeString = utils.getBasicAuth(basicAuthValue, msoKey)
221 HttpClient httpClient = getHttpClientFactory().newJsonClient(new URL(url), ONAPComponents.SO)
222 // httpClient.addAdditionalHeader("Authorization", encodeString)
223 httpClient.addAdditionalHeader("Authorization", basicAuth)
224 httpClient.addAdditionalHeader("Accept", "application/json")
225 Response httpResponse = httpClient.delete(requestBody)
226 handleNSSMFWFResponse(httpResponse, execution)
228 } catch (BpmnError e) {
231 String msg = "Exception in DeleteCommunicationService.preRequestSend2NSMF. " + any.getCause()
233 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
236 LOGGER.debug("exit preRequestSend2NSMF")
240 * prepare update operation status
243 private void handleNSSMFWFResponse(Response httpResponse, DelegateExecution execution){
244 LOGGER.debug(" ======== STARTED prepareUpdateOperationStatus Process ======== ")
246 int nsmfResponseCode = httpResponse.getStatus()
247 LOGGER.debug("nsmfResponseCode${nsmfResponseCode}")
249 if (nsmfResponseCode >= 200 && nsmfResponseCode < 204 && httpResponse.hasEntity()) {
250 String nsmfResponse = httpResponse.readEntity(String.class)
251 def e2eOperationId = jsonUtil.getJsonValue(nsmfResponse, "operationId")
252 execution.setVariable("e2eOperationId", e2eOperationId)
253 execution.setVariable("progress","20")
254 execution.setVariable("operationContent","waiting nsmf service delete finished")
256 execution.setVariable("currentCycle",0)
257 execution.setVariable("isNSMFTimeOut", "no")
258 execution.setVariable("isNSMFWFRspSucceed","yes")
262 String serviceName = execution.getVariable("serviceInstanceName")
263 execution.setVariable("progress", "100")
264 execution.setVariable("result", "error")
265 execution.setVariable("operationContent", "terminate service failure.")
266 execution.setVariable("reason","NSMF WF asynchronous response failed, status Code:${nsmfResponseCode}")
267 execution.setVariable("isNSMFWFRspSucceed","no")
268 LOGGER.error("nsmf async response error,nsmfResponseCode:${nsmfResponseCode},serivceName:${serviceName}")
270 setOperationStatus(execution)
271 LOGGER.debug("======== COMPLETED prepareUpdateOperationStatus Process ======== ")
275 * prepare to call sub process
278 void prepareCallCheckProcessStatus(DelegateExecution execution)
280 LOGGER.debug(PREFIX + "prepareCallCheckProcessStatus Start")
282 def successConditions = new ArrayList<>()
283 successConditions.add("finished")
284 execution.setVariable("successConditions", successConditions)
286 def errorConditions = new ArrayList<>()
287 errorConditions.add("error")
288 execution.setVariable("errorConditions", errorConditions)
290 execution.setVariable("processServiceType", "communication service")
291 execution.setVariable("subOperationType", "DELETE")
292 execution.setVariable("initProgress", 20)
293 execution.setVariable("endProgress",90)
295 execution.setVariable("timeOut", TIMEOUT)
297 LOGGER.debug(PREFIX + "prepareCallCheckProcessStatus Exit")
301 * delete communication profile from AAI
304 void delCSProfileFromAAI(DelegateExecution execution)
306 LOGGER.debug("start delete communication service profile from AAI")
307 String globalSubscriberId = execution.getVariable("globalSubscriberId")
308 String serviceType = execution.getVariable("serviceType")
309 String serviceInstanceId = execution.getVariable("serviceInstanceId")
314 AAIPluralResourceUri resourceUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(globalSubscriberId).serviceSubscription(serviceType).serviceInstance(serviceInstanceId).communicationServiceProfiles())
315 AAIResultWrapper wrapper = getAAIClient().get(resourceUri, NotFoundException.class)
316 Optional<CommunicationServiceProfiles> csProfilesOpt = wrapper.asBean(CommunicationServiceProfiles.class)
317 if(csProfilesOpt.isPresent()){
318 CommunicationServiceProfiles csProfiles = csProfilesOpt.get()
319 CommunicationServiceProfile csProfile = csProfiles.getCommunicationServiceProfile().get(0)
320 profileId = csProfile ? csProfile.getProfileId() : ""
322 resourceUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(globalSubscriberId).serviceSubscription(serviceType).serviceInstance(serviceInstanceId).communicationServiceProfile(profileId))
323 if (!getAAIClient().exists(resourceUri)) {
324 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "communication service profile was not found in aai")
327 getAAIClient().delete(resourceUri)
328 LOGGER.debug("end delete communication service profile from AAI")
332 String msg = "delete communication service profile from aai failed! cause-"+any.getCause()
333 LOGGER.error(any.printStackTrace())
334 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg);
340 * delete communication service from AAI
343 void delCSFromAAI(DelegateExecution execution)
347 LOGGER.debug("start delete communication service from AAI")
348 AAIResourceUri serviceInstanceUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(execution.getVariable("globalSubscriberId")).serviceSubscription(execution.getVariable("serviceType")).serviceInstance(execution.getVariable("serviceInstanceId")))
349 getAAIClient().delete(serviceInstanceUri)
351 execution.setVariable("progress", "100")
352 execution.setVariable("result", "finished")
353 execution.setVariable("operationContent", "CSMF completes service terminated.")
354 setOperationStatus(execution)
355 LOGGER.debug("end delete communication service from AAI")
359 LOGGER.error("Error occured within delCSFromAAI method, cause: ${any.getCause()} ")
360 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Error occured during delete communication service from aai")
364 void sendSyncError(DelegateExecution execution)
366 LOGGER.debug("Starting sendSyncError")
369 String errorMessage = "Sending Sync Error."
370 if (execution.getVariable("WorkflowException") instanceof WorkflowException) {
371 WorkflowException wfe = execution.getVariable("WorkflowException")
372 errorMessage = wfe.getErrorMessage()
375 String buildworkflowException =
376 """<aetgt:WorkflowException xmlns:aetgt="http://org.onap/so/workflow/schema/v1">
377 <aetgt:ErrorMessage>${MsoUtils.xmlEscape(errorMessage)}</aetgt:ErrorMessage>
378 <aetgt:ErrorCode>7000</aetgt:ErrorCode>
379 </aetgt:WorkflowException>"""
381 LOGGER.debug(buildworkflowException)
382 sendWorkflowResponse(execution, 500, buildworkflowException)
384 } catch (Exception ex) {
385 LOGGER.error("Sending Sync Error Activity Failed. " + "\n" + ex.getMessage())
390 * prepare update operation status
393 void preFailedOperationStatus(DelegateExecution execution)
395 LOGGER.debug(" ======== STARTED preFailedOperationStatus Process ======== ")
397 execution.setVariable("progress", "100")
398 execution.setVariable("result", "error")
399 execution.setVariable("operationContent", "terminate service failure")
401 WorkflowException wfex = execution.getVariable("WorkflowException") as WorkflowException
402 String errorMessage = wfex.getErrorMessage()
403 errorMessage = errorMessage.length() > 200 ? errorMessage.substring(0,200) + "......" : errorMessage
404 execution.setVariable("reason", errorMessage)
405 setOperationStatus(execution)
407 LOGGER.debug("======== COMPLETED prepareEndOperationStatus Process ======== ")
411 * prepare Operation status
413 * @param operationType
415 private void setOperationStatus(DelegateExecution execution)
417 OperationStatus operationStatus = new OperationStatus()
418 operationStatus.setServiceId(execution.getVariable("serviceInstanceId"))
419 operationStatus.setOperationId(execution.getVariable("operationId"))
420 operationStatus.setUserId(execution.getVariable("globalSubscriberId"))
421 //interface not support update
422 operationStatus.setServiceName(execution.getVariable("serviceInstanceName"))
423 operationStatus.setResult(execution.getVariable("result"))
424 operationStatus.setProgress(execution.getVariable("progress"))
425 operationStatus.setOperationContent(execution.getVariable("operationContent"))
426 operationStatus.setReason(execution.getVariable("reason")?:"")
427 operationStatus.setOperation("DELETE")
429 requestDBUtil.prepareUpdateOperationStatus(execution, operationStatus)
432 void prepareFailureStatus(DelegateExecution execution)
434 execution.setVariable("result", "finished")
435 execution.setVariable("progress", "100")
436 execution.setVariable("operationContent", "terminate service failure.")
437 setOperationStatus(execution)
438 LOGGER.debug("${PREFIX}-prepareFailureStatus,result:${execution.getVariable("result")}, reason: ${execution.getVariable("reason")}")
442 * check request json and save parameter to execution
445 * @param isErrorException
448 private void checkAndSetRequestParam(String siRequest, String paraName, boolean isErrorException, DelegateExecution execution)
451 String paramValue = jsonUtil.getJsonValue(siRequest, paraName)
452 if (isBlank(paramValue)) {
453 msg = "Input ${paraName} is null"
457 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
461 execution.setVariable(paraName, paramValue)