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
22 import org.onap.aaiclient.client.aai.entities.uri.AAISimpleUri
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
54 class DeleteCommunicationService extends AbstractServiceTaskProcessor {
55 private final String PREFIX ="DeleteCommunicationService"
56 private final Long TIMEOUT = 60 * 60 * 1000
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)
64 void preProcessRequest(DelegateExecution execution) {
65 execution.setVariable("prefix",PREFIX)
68 LOGGER.trace("Starting preProcessRequest")
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")
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)
84 LOGGER.info("Input Request: ${siRequest}, reqId: ${requestId}, serviceInstanceId: ${serviceInstanceId}")
87 checkAndSetRequestParam(siRequest,"globalSubscriberId",false,execution)
88 checkAndSetRequestParam(siRequest,"serviceType",false,execution)
89 checkAndSetRequestParam(siRequest,"operationId",false,execution)
91 } catch (BpmnError e) {
94 msg = "Exception in preProcessRequest " + any.getCause()
96 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
98 LOGGER.trace("Exit preProcessRequest")
103 * prepare update operation status
106 void preInitUpdateOperationStatus(DelegateExecution execution){
107 LOGGER.trace(" ======== STARTED initUpdateOperationStatus Process ======== ")
109 execution.setVariable("result","processing")
110 execution.setVariable("progress","0")
111 execution.setVariable("operationContent","delete communication service operation start")
112 setOperationStatus(execution)
115 LOGGER.error("Exception Occured Processing initUpdateOperationStatus. Exception is:\n" + e)
116 execution.setVariable("CVFMI_ErrorResponse", "Error Occurred during initUpdateOperationStatus Method:\n" + e.getMessage())
118 LOGGER.trace("======== COMPLETED initUpdateOperationStatus Process ======== ")
125 void sendSyncResponse(DelegateExecution execution) {
126 LOGGER.debug("Begin sendSyncResponse")
129 String operationId = execution.getVariable("operationId")
130 String syncResponse = """{"operationId":"${operationId}"}""".trim()
131 sendWorkflowResponse(execution, 202, syncResponse)
133 } catch (Exception ex) {
134 String msg = "Exception in sendSyncResponse: " + ex.getMessage()
135 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
137 LOGGER.debug("Exit sendSyncResponse")
141 * query CommunicationSerive from AAI
142 * save e2eslice-service instance id and service name
145 void queryCommunicationSeriveFromAAI(DelegateExecution execution)
147 LOGGER.trace(" ***** begin queryCommunicationSeriveFromAAI *****")
148 String serviceInstanceId = execution.getVariable("serviceInstanceId")
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)
155 String serviceInstName = si.get()?.getServiceInstanceName()
156 String e2eSliceServiceInstId
159 List<Relationship> relationshipList = si.get().getRelationshipList()?.getRelationship()
160 for (Relationship relationship : relationshipList)
162 String relatedTo = relationship.getRelatedTo()
163 if (relatedTo == "service-instance")
165 String relatedLink = relationship.getRelatedLink()?:""
166 e2eSliceServiceInstId = relatedLink ? relatedLink.substring(relatedLink.lastIndexOf("/") + 1,relatedLink.length()) : ""
171 execution.setVariable("e2eSliceServiceInstanceId", e2eSliceServiceInstId)
172 execution.setVariable("serviceInstanceName", serviceInstName ?: "")
173 LOGGER.info("communication-service Id: ${serviceInstanceId}, e2eslice-service Id: ${e2eSliceServiceInstId}, serviceName: ${serviceInstName}")
175 LOGGER.debug(" ***** Exit queryCommunicationSeriveFromAAI *****")
181 * @param aaiObjectName
183 * @return AAIResultWrapper
185 private AAIResultWrapper queryAAI(DelegateExecution execution, AAIObjectName aaiObjectName, String instanceId, String errorMsg)
187 String globalSubscriberId = execution.getVariable("globalSubscriberId")
188 String serviceType = execution.getVariable("serviceType")
190 AAIResourceUri resourceUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(globalSubscriberId).serviceSubscription(serviceType).serviceInstance(instanceId))
191 if (!getAAIClient().exists(resourceUri)) {
192 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, errorMsg)
194 AAIResultWrapper wrapper = getAAIClient().get(resourceUri, NotFoundException.class)
200 * 再次调用deleteE2EServiceInstance接口,然后获取到operationid,
202 void sendRequest2NSMFWF(DelegateExecution execution) {
203 LOGGER.debug("begin preRequestSend2NSMF")
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")}"
209 String requestBody = """
211 "globalSubscriberId": "${execution.getVariable("globalSubscriberId")}",
212 "serviceType": "${execution.getVariable("serviceType")}"
215 requestBody.replaceAll("\\s+", "")
217 String msoKey = UrnPropertiesReader.getVariable("mso.msoKey", execution)
218 String basicAuth = UrnPropertiesReader.getVariable("mso.infra.endpoint.auth", execution)
219 // String basicAuthValue = utils.encrypt(basicAuth, msoKey)
220 // String encodeString = utils.getBasicAuth(basicAuthValue, msoKey)
222 HttpClient httpClient = getHttpClientFactory().newJsonClient(new URL(url), ONAPComponents.SO)
223 // httpClient.addAdditionalHeader("Authorization", encodeString)
224 httpClient.addAdditionalHeader("Authorization", basicAuth)
225 httpClient.addAdditionalHeader("Accept", "application/json")
226 Response httpResponse = httpClient.delete(requestBody)
227 handleNSSMFWFResponse(httpResponse, execution)
229 } catch (BpmnError e) {
232 String msg = "Exception in DeleteCommunicationService.preRequestSend2NSMF. " + any.getCause()
234 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
237 LOGGER.debug("exit preRequestSend2NSMF")
241 * prepare update operation status
244 private void handleNSSMFWFResponse(Response httpResponse, DelegateExecution execution){
245 LOGGER.debug(" ======== STARTED prepareUpdateOperationStatus Process ======== ")
247 int nsmfResponseCode = httpResponse.getStatus()
248 LOGGER.debug("nsmfResponseCode${nsmfResponseCode}")
250 if (nsmfResponseCode >= 200 && nsmfResponseCode < 204 && httpResponse.hasEntity()) {
251 String nsmfResponse = httpResponse.readEntity(String.class)
252 def e2eOperationId = jsonUtil.getJsonValue(nsmfResponse, "operationId")
253 execution.setVariable("e2eOperationId", e2eOperationId)
254 execution.setVariable("progress","20")
255 execution.setVariable("operationContent","waiting nsmf service delete finished")
257 execution.setVariable("currentCycle",0)
258 execution.setVariable("isNSMFTimeOut", "no")
259 execution.setVariable("isNSMFWFRspSucceed","yes")
263 String serviceName = execution.getVariable("serviceInstanceName")
264 execution.setVariable("progress", "100")
265 execution.setVariable("result", "error")
266 execution.setVariable("operationContent", "terminate service failure.")
267 execution.setVariable("reason","NSMF WF asynchronous response failed, status Code:${nsmfResponseCode}")
268 execution.setVariable("isNSMFWFRspSucceed","no")
269 LOGGER.error("nsmf async response error,nsmfResponseCode:${nsmfResponseCode},serivceName:${serviceName}")
271 setOperationStatus(execution)
272 LOGGER.debug("======== COMPLETED prepareUpdateOperationStatus Process ======== ")
276 * prepare to call sub process
279 void prepareCallCheckProcessStatus(DelegateExecution execution)
281 LOGGER.debug(PREFIX + "prepareCallCheckProcessStatus Start")
283 def successConditions = new ArrayList<>()
284 successConditions.add("finished")
285 execution.setVariable("successConditions", successConditions)
287 def errorConditions = new ArrayList<>()
288 errorConditions.add("error")
289 execution.setVariable("errorConditions", errorConditions)
291 execution.setVariable("processServiceType", "communication service")
292 execution.setVariable("subOperationType", "DELETE")
293 execution.setVariable("initProgress", 20)
294 execution.setVariable("endProgress",90)
296 execution.setVariable("timeOut", TIMEOUT)
298 LOGGER.debug(PREFIX + "prepareCallCheckProcessStatus Exit")
302 * delete communication profile from AAI
305 void delCSProfileFromAAI(DelegateExecution execution)
307 LOGGER.debug("start delete communication service profile from AAI")
308 String globalSubscriberId = execution.getVariable("globalSubscriberId")
309 String serviceType = execution.getVariable("serviceType")
310 String serviceInstanceId = execution.getVariable("serviceInstanceId")
315 AAIPluralResourceUri resourceUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(globalSubscriberId).serviceSubscription(serviceType).serviceInstance(serviceInstanceId).communicationServiceProfiles())
316 AAIResultWrapper wrapper = getAAIClient().get(resourceUri, NotFoundException.class)
317 Optional<CommunicationServiceProfiles> csProfilesOpt = wrapper.asBean(CommunicationServiceProfiles.class)
318 if(csProfilesOpt.isPresent()){
319 CommunicationServiceProfiles csProfiles = csProfilesOpt.get()
320 CommunicationServiceProfile csProfile = csProfiles.getCommunicationServiceProfile().get(0)
321 profileId = csProfile ? csProfile.getProfileId() : ""
323 AAISimpleUri profileUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(globalSubscriberId).serviceSubscription(serviceType).serviceInstance(serviceInstanceId).communicationServiceProfile(profileId))
324 if (!getAAIClient().exists(profileUri)) {
325 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "communication service profile was not found in aai")
328 getAAIClient().delete(profileUri)
329 LOGGER.debug("end delete communication service profile from AAI")
333 String msg = "delete communication service profile from aai failed! cause-"+any.getCause()
334 LOGGER.error(any.printStackTrace())
335 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg);
341 * delete communication service from AAI
344 void delCSFromAAI(DelegateExecution execution)
348 LOGGER.debug("start delete communication service from AAI")
349 AAIResourceUri serviceInstanceUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(execution.getVariable("globalSubscriberId")).serviceSubscription(execution.getVariable("serviceType")).serviceInstance(execution.getVariable("serviceInstanceId")))
350 getAAIClient().delete(serviceInstanceUri)
352 execution.setVariable("progress", "100")
353 execution.setVariable("result", "finished")
354 execution.setVariable("operationContent", "CSMF completes service terminated.")
355 setOperationStatus(execution)
356 LOGGER.debug("end delete communication service from AAI")
360 LOGGER.error("Error occured within delCSFromAAI method, cause: ${any.getCause()} ")
361 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Error occured during delete communication service from aai")
365 void sendSyncError(DelegateExecution execution)
367 LOGGER.debug("Starting sendSyncError")
370 String errorMessage = "Sending Sync Error."
371 if (execution.getVariable("WorkflowException") instanceof WorkflowException) {
372 WorkflowException wfe = execution.getVariable("WorkflowException")
373 errorMessage = wfe.getErrorMessage()
376 String buildworkflowException =
377 """<aetgt:WorkflowException xmlns:aetgt="http://org.onap/so/workflow/schema/v1">
378 <aetgt:ErrorMessage>${MsoUtils.xmlEscape(errorMessage)}</aetgt:ErrorMessage>
379 <aetgt:ErrorCode>7000</aetgt:ErrorCode>
380 </aetgt:WorkflowException>"""
382 LOGGER.debug(buildworkflowException)
383 sendWorkflowResponse(execution, 500, buildworkflowException)
385 } catch (Exception ex) {
386 LOGGER.error("Sending Sync Error Activity Failed. " + "\n" + ex.getMessage())
391 * prepare update operation status
394 void preFailedOperationStatus(DelegateExecution execution)
396 LOGGER.debug(" ======== STARTED preFailedOperationStatus Process ======== ")
398 execution.setVariable("progress", "100")
399 execution.setVariable("result", "error")
400 execution.setVariable("operationContent", "terminate service failure")
402 WorkflowException wfex = execution.getVariable("WorkflowException") as WorkflowException
403 String errorMessage = wfex.getErrorMessage()
404 errorMessage = errorMessage.length() > 200 ? errorMessage.substring(0,200) + "......" : errorMessage
405 execution.setVariable("reason", errorMessage)
406 setOperationStatus(execution)
408 LOGGER.debug("======== COMPLETED prepareEndOperationStatus Process ======== ")
412 * prepare Operation status
414 * @param operationType
416 private void setOperationStatus(DelegateExecution execution)
418 OperationStatus operationStatus = new OperationStatus()
419 operationStatus.setServiceId(execution.getVariable("serviceInstanceId"))
420 operationStatus.setOperationId(execution.getVariable("operationId"))
421 operationStatus.setUserId(execution.getVariable("globalSubscriberId"))
422 //interface not support update
423 operationStatus.setServiceName(execution.getVariable("serviceInstanceName"))
424 operationStatus.setResult(execution.getVariable("result"))
425 operationStatus.setProgress(execution.getVariable("progress"))
426 operationStatus.setOperationContent(execution.getVariable("operationContent"))
427 operationStatus.setReason(execution.getVariable("reason")?:"")
428 operationStatus.setOperation("DELETE")
430 requestDBUtil.prepareUpdateOperationStatus(execution, operationStatus)
433 void prepareFailureStatus(DelegateExecution execution)
435 execution.setVariable("result", "finished")
436 execution.setVariable("progress", "100")
437 execution.setVariable("operationContent", "terminate service failure.")
438 setOperationStatus(execution)
439 LOGGER.debug("${PREFIX}-prepareFailureStatus,result:${execution.getVariable("result")}, reason: ${execution.getVariable("reason")}")
443 * check request json and save parameter to execution
446 * @param isErrorException
449 private void checkAndSetRequestParam(String siRequest, String paraName, boolean isErrorException, DelegateExecution execution)
452 String paramValue = jsonUtil.getJsonValue(siRequest, paraName)
453 if (isBlank(paramValue)) {
454 msg = "Input ${paraName} is null"
458 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
462 execution.setVariable(paraName, paramValue)