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("Accept", "application/json")
224 Response httpResponse = httpClient.delete(requestBody)
225 handleNSSMFWFResponse(httpResponse, execution)
227 } catch (BpmnError e) {
230 String msg = "Exception in DeleteCommunicationService.preRequestSend2NSMF. " + any.getCause()
232 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
235 LOGGER.debug("exit preRequestSend2NSMF")
239 * prepare update operation status
242 private void handleNSSMFWFResponse(Response httpResponse, DelegateExecution execution){
243 LOGGER.debug(" ======== STARTED prepareUpdateOperationStatus Process ======== ")
245 int nsmfResponseCode = httpResponse.getStatus()
246 LOGGER.debug("nsmfResponseCode${nsmfResponseCode}")
248 if (nsmfResponseCode >= 200 && nsmfResponseCode < 204 && httpResponse.hasEntity()) {
249 String nsmfResponse = httpResponse.readEntity(String.class)
250 def e2eOperationId = jsonUtil.getJsonValue(nsmfResponse, "operationId")
251 execution.setVariable("e2eOperationId", e2eOperationId)
252 execution.setVariable("progress","20")
253 execution.setVariable("operationContent","waiting nsmf service delete finished")
255 execution.setVariable("currentCycle",0)
256 execution.setVariable("isNSMFTimeOut", "no")
257 execution.setVariable("isNSMFWFRspSucceed","yes")
261 String serviceName = execution.getVariable("serviceInstanceName")
262 execution.setVariable("progress", "100")
263 execution.setVariable("result", "error")
264 execution.setVariable("operationContent", "terminate service failure.")
265 execution.setVariable("reason","NSMF WF asynchronous response failed, status Code:${nsmfResponseCode}")
266 execution.setVariable("isNSMFWFRspSucceed","no")
267 LOGGER.error("nsmf async response error,nsmfResponseCode:${nsmfResponseCode},serivceName:${serviceName}")
269 setOperationStatus(execution)
270 LOGGER.debug("======== COMPLETED prepareUpdateOperationStatus Process ======== ")
274 * prepare to call sub process
277 void prepareCallCheckProcessStatus(DelegateExecution execution)
279 LOGGER.debug(PREFIX + "prepareCallCheckProcessStatus Start")
281 def successConditions = new ArrayList<>()
282 successConditions.add("finished")
283 execution.setVariable("successConditions", successConditions)
285 def errorConditions = new ArrayList<>()
286 errorConditions.add("error")
287 execution.setVariable("errorConditions", errorConditions)
289 execution.setVariable("processServiceType", "communication service")
290 execution.setVariable("subOperationType", "DELETE")
291 execution.setVariable("initProgress", 20)
292 execution.setVariable("endProgress",90)
294 execution.setVariable("timeOut", TIMEOUT)
296 LOGGER.debug(PREFIX + "prepareCallCheckProcessStatus Exit")
300 * delete communication profile from AAI
303 void delCSProfileFromAAI(DelegateExecution execution)
305 LOGGER.debug("start delete communication service profile from AAI")
306 String globalSubscriberId = execution.getVariable("globalSubscriberId")
307 String serviceType = execution.getVariable("serviceType")
308 String serviceInstanceId = execution.getVariable("serviceInstanceId")
313 AAIPluralResourceUri resourceUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(globalSubscriberId).serviceSubscription(serviceType).serviceInstance(serviceInstanceId).communicationServiceProfiles())
314 AAIResultWrapper wrapper = getAAIClient().get(resourceUri, NotFoundException.class)
315 Optional<CommunicationServiceProfiles> csProfilesOpt = wrapper.asBean(CommunicationServiceProfiles.class)
316 if(csProfilesOpt.isPresent()){
317 CommunicationServiceProfiles csProfiles = csProfilesOpt.get()
318 CommunicationServiceProfile csProfile = csProfiles.getCommunicationServiceProfile().get(0)
319 profileId = csProfile ? csProfile.getProfileId() : ""
321 resourceUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(globalSubscriberId).serviceSubscription(serviceType).serviceInstance(serviceInstanceId).communicationServiceProfile(profileId))
322 if (!getAAIClient().exists(resourceUri)) {
323 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "communication service profile was not found in aai")
326 getAAIClient().delete(resourceUri)
327 LOGGER.debug("end delete communication service profile from AAI")
331 String msg = "delete communication service profile from aai failed! cause-"+any.getCause()
332 LOGGER.error(any.printStackTrace())
333 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg);
339 * delete communication service from AAI
342 void delCSFromAAI(DelegateExecution execution)
346 LOGGER.debug("start delete communication service from AAI")
347 AAIResourceUri serviceInstanceUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(execution.getVariable("globalSubscriberId")).serviceSubscription(execution.getVariable("serviceType")).serviceInstance(execution.getVariable("serviceInstanceId")))
348 getAAIClient().delete(serviceInstanceUri)
350 execution.setVariable("progress", "100")
351 execution.setVariable("result", "finished")
352 execution.setVariable("operationContent", "CSMF completes service terminated.")
353 setOperationStatus(execution)
354 LOGGER.debug("end delete communication service from AAI")
358 LOGGER.error("Error occured within delCSFromAAI method, cause: ${any.getCause()} ")
359 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Error occured during delete communication service from aai")
363 void sendSyncError(DelegateExecution execution)
365 LOGGER.debug("Starting sendSyncError")
368 String errorMessage = "Sending Sync Error."
369 if (execution.getVariable("WorkflowException") instanceof WorkflowException) {
370 WorkflowException wfe = execution.getVariable("WorkflowException")
371 errorMessage = wfe.getErrorMessage()
374 String buildworkflowException =
375 """<aetgt:WorkflowException xmlns:aetgt="http://org.onap/so/workflow/schema/v1">
376 <aetgt:ErrorMessage>${MsoUtils.xmlEscape(errorMessage)}</aetgt:ErrorMessage>
377 <aetgt:ErrorCode>7000</aetgt:ErrorCode>
378 </aetgt:WorkflowException>"""
380 LOGGER.debug(buildworkflowException)
381 sendWorkflowResponse(execution, 500, buildworkflowException)
383 } catch (Exception ex) {
384 LOGGER.error("Sending Sync Error Activity Failed. " + "\n" + ex.getMessage())
389 * prepare update operation status
392 void preFailedOperationStatus(DelegateExecution execution)
394 LOGGER.debug(" ======== STARTED preFailedOperationStatus Process ======== ")
396 execution.setVariable("progress", "100")
397 execution.setVariable("result", "error")
398 execution.setVariable("operationContent", "terminate service failure")
400 WorkflowException wfex = execution.getVariable("WorkflowException") as WorkflowException
401 String errorMessage = wfex.getErrorMessage()
402 errorMessage = errorMessage.length() > 200 ? errorMessage.substring(0,200) + "......" : errorMessage
403 execution.setVariable("reason", errorMessage)
404 setOperationStatus(execution)
406 LOGGER.debug("======== COMPLETED prepareEndOperationStatus Process ======== ")
410 * prepare Operation status
412 * @param operationType
414 private void setOperationStatus(DelegateExecution execution)
416 OperationStatus operationStatus = new OperationStatus()
417 operationStatus.setServiceId(execution.getVariable("serviceInstanceId"))
418 operationStatus.setOperationId(execution.getVariable("operationId"))
419 operationStatus.setUserId(execution.getVariable("globalSubscriberId"))
420 //interface not support update
421 operationStatus.setServiceName(execution.getVariable("serviceInstanceName"))
422 operationStatus.setResult(execution.getVariable("result"))
423 operationStatus.setProgress(execution.getVariable("progress"))
424 operationStatus.setOperationContent(execution.getVariable("operationContent"))
425 operationStatus.setReason(execution.getVariable("reason")?:"")
426 operationStatus.setOperation("DELETE")
428 requestDBUtil.prepareUpdateOperationStatus(execution, operationStatus)
431 void prepareFailureStatus(DelegateExecution execution)
433 execution.setVariable("result", "finished")
434 execution.setVariable("progress", "100")
435 execution.setVariable("operationContent", "terminate service failure.")
436 setOperationStatus(execution)
437 LOGGER.debug("${PREFIX}-prepareFailureStatus,result:${execution.getVariable("result")}, reason: ${execution.getVariable("reason")}")
441 * check request json and save parameter to execution
444 * @param isErrorException
447 private void checkAndSetRequestParam(String siRequest, String paraName, boolean isErrorException, DelegateExecution execution)
450 String paramValue = jsonUtil.getJsonValue(siRequest, paraName)
451 if (isBlank(paramValue)) {
452 msg = "Input ${paraName} is null"
456 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
460 execution.setVariable(paraName, paramValue)