2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2019 Huawei Technologies Co., Ltd. All rights reserved.
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
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=========================================================
21 package org.onap.so.bpmn.infrastructure.scripts
24 import org.camunda.bpm.engine.delegate.BpmnError
25 import org.camunda.bpm.engine.delegate.DelegateExecution
26 import org.onap.aai.domain.yang.*
27 import org.onap.aaiclient.client.aai.AAIResourcesClient
28 import org.onap.aaiclient.client.aai.entities.AAIResultWrapper
29 import org.onap.aaiclient.client.aai.entities.uri.AAIPluralResourceUri
30 import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri
31 import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory
32 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder
33 import org.onap.logging.filter.base.ErrorCode
34 import org.onap.so.beans.nsmf.CustomerInfo
35 import org.onap.so.beans.nsmf.NetworkType
36 import org.onap.so.beans.nsmf.NssInstance
37 import org.onap.so.beans.nsmf.OperationType
38 import org.onap.so.beans.nsmf.OrchestrationStatusEnum
39 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor
40 import org.onap.so.bpmn.common.scripts.ExceptionUtil
41 import org.onap.so.bpmn.common.scripts.MsoUtils
42 import org.onap.so.bpmn.common.scripts.RequestDBUtil
43 import org.onap.so.bpmn.core.WorkflowException
44 import org.onap.so.bpmn.core.json.JsonUtils
45 import org.onap.so.db.request.beans.OperationStatus
46 import org.onap.so.logger.LoggingAnchor
47 import org.onap.so.logger.MessageEnum
48 import org.slf4j.Logger
49 import org.slf4j.LoggerFactory
51 import javax.ws.rs.NotFoundException
52 import java.util.function.Consumer
54 import static org.apache.commons.lang3.StringUtils.isBlank
57 * This groovy class supports the <class>ActivateSliceService.bpmn</class> process.
58 * AlaCarte flow for 1702 slice service activate
62 class ActivateSliceService extends AbstractServiceTaskProcessor {
65 String Prefix = "ACTSS_"
67 ExceptionUtil exceptionUtil = new ExceptionUtil()
69 JsonUtils jsonUtil = new JsonUtils()
71 RequestDBUtil requestDBUtil = new RequestDBUtil()
73 AAIResourcesClient client = getAAIClient()
75 private static final Logger logger = LoggerFactory.getLogger(ActivateSliceService.class)
77 void preProcessRequest(DelegateExecution execution) {
78 logger.debug(Prefix + "preProcessRequest Start")
79 execution.setVariable("prefix", Prefix)
83 // check for incoming json message/input
84 String siRequest = Objects.requireNonNull(execution.getVariable("bpmnRequest"))
85 logger.debug(siRequest)
87 String requestId = execution.getVariable("mso-request-id")
88 execution.setVariable("msoRequestId", requestId)
89 logger.info("Input Request:" + siRequest + " reqId:" + requestId)
91 String serviceInstanceId = execution.getVariable("serviceInstanceId")
92 if (isBlank(serviceInstanceId)) {
93 msg = "Input serviceInstanceId' is null"
94 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
96 String source = jsonUtil.getJsonValue(siRequest, "source")
97 execution.setVariable("source", source)
100 String globalSubscriberId = jsonUtil.getJsonValue(siRequest, "globalSubscriberId")
101 if (isBlank(globalSubscriberId)) {
102 msg = "Input globalSubscriberId' is null"
104 execution.setVariable("globalSubscriberId", "5GCustomer")
106 execution.setVariable("globalSubscriberId", globalSubscriberId)
110 String subscriptionServiceType = jsonUtil.getJsonValue(siRequest, "serviceType")
111 if (isBlank(subscriptionServiceType)) {
112 msg = "Input subscriptionServiceType is null"
114 execution.setVariable("subscriptionServiceType", "5G")
116 execution.setVariable("subscriptionServiceType", subscriptionServiceType)
118 String operationId = Objects.requireNonNull(jsonUtil.getJsonValue(siRequest, "operationId"))
119 execution.setVariable("operationId", operationId)
121 String operationType = Objects.requireNonNull(execution.getVariable("operationType"))
122 logger.info("operationType is " + execution.getVariable("operationType") )
124 CustomerInfo customerInfo = CustomerInfo.builder().operationId(operationId)
125 .operationType(Objects.requireNonNull(OperationType.getOperationType(operationType)))
126 .globalSubscriberId(globalSubscriberId).serviceInstanceId(serviceInstanceId)
127 .subscriptionServiceType(subscriptionServiceType)
130 execution.setVariable("customerInfo", customerInfo)
132 } catch (BpmnError e) {
134 } catch (Exception ex) {
135 msg = "Exception in preProcessRequest " + ex.getMessage()
137 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
139 logger.debug(Prefix + "preProcessRequest Exit")
143 * Init the service Operation Status
145 def prepareInitServiceOperationStatus = { DelegateExecution execution ->
146 logger.debug(Prefix + "prepareActivateServiceOperationStatus Start")
148 CustomerInfo customerInfo = execution.getVariable("customerInfo") as CustomerInfo
149 String serviceId = customerInfo.getServiceInstanceId()
150 String operationId = customerInfo.getOperationId()
151 String operationType = customerInfo.getOperationType().getType()
152 String userId = customerInfo.getGlobalSubscriberId()
153 String result = "processing"
154 String progress = "0"
156 String operationContent = "Prepare service activation"
158 execution.setVariable("e2eserviceInstanceId", serviceId)
159 //execution.setVariable("operationType", operationType)
161 OperationStatus initStatus = new OperationStatus()
162 initStatus.setServiceId(serviceId)
163 initStatus.setOperationId(operationId)
164 initStatus.setOperation(operationType)
165 initStatus.setUserId(userId)
166 initStatus.setResult(result)
167 initStatus.setProgress(progress)
168 initStatus.setReason(reason)
169 initStatus.setOperationContent(operationContent)
171 requestDBUtil.prepareUpdateOperationStatus(execution, initStatus)
173 } catch (Exception e) {
174 logger.error(LoggingAnchor.FIVE, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
175 "Exception Occured Processing prepareInitServiceOperationStatus.", "BPMN",
176 ErrorCode.UnknownError.getValue(), "Exception is:\n" + e)
177 execution.setVariable("CVFMI_ErrorResponse",
178 "Error Occurred during prepareInitServiceOperationStatus Method:\n" + e.getMessage())
180 logger.debug(Prefix + "prepareInitServiceOperationStatus Exit")
184 def sendSyncResponse = { DelegateExecution execution ->
185 logger.debug(Prefix + "sendSyncResponse Start")
187 CustomerInfo customerInfo = execution.getVariable("customerInfo") as CustomerInfo
188 String operationId = customerInfo.getOperationId()
190 // RESTResponse for API Handler (APIH) Reply Task
191 String Activate5GsliceServiceRestRequest = """{"operationId":"${operationId}"}""".trim()
192 logger.debug(" sendSyncResponse to APIH:" + "\n" + Activate5GsliceServiceRestRequest)
194 sendWorkflowResponse(execution, 202, Activate5GsliceServiceRestRequest)
195 execution.setVariable("sentSyncResponse", true)
196 } catch (Exception ex) {
197 String msg = "Exceptuion in sendSyncResponse:" + ex.getMessage()
199 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
201 logger.debug(Prefix + "sendSyncResponse Exit")
205 public sendSyncError = { DelegateExecution execution ->
206 logger.debug("sendSyncError Start")
209 if (execution.getVariable("WorkflowException") instanceof WorkflowException) {
210 WorkflowException wfe = execution.getVariable("WorkflowException") as WorkflowException
211 errorMessage = wfe.getErrorMessage()
213 errorMessage = "Sending Sync Error."
216 String buildWorkflowException =
217 """<aetgt:WorkflowException xmlns:aetgt="http://org.onap/so/workflow/schema/v1">
218 <aetgt:ErrorMessage>${MsoUtils.xmlEscape(errorMessage)}</aetgt:ErrorMessage>
219 <aetgt:ErrorCode>7000</aetgt:ErrorCode>
220 </aetgt:WorkflowException>"""
222 logger.debug(buildWorkflowException)
223 sendWorkflowResponse(execution, 500, buildWorkflowException)
225 } catch (Exception ex) {
226 logger.debug("Sending Sync Error Activity Failed. " + "\n" + ex.getMessage())
228 logger.debug(Prefix + "sendSyncError Exit")
231 def checkAAIOrchStatusOfE2ESlice = { DelegateExecution execution ->
232 logger.debug(Prefix + "CheckAAIOrchStatus Start")
233 execution.setVariable("isContinue", "false")
234 CustomerInfo customerInfo = execution.getVariable("customerInfo") as CustomerInfo
236 String serviceInstanceId = customerInfo.serviceInstanceId
237 String globalSubscriberId = customerInfo.globalSubscriberId
238 String subscriptionServiceType = customerInfo.subscriptionServiceType
240 logger.debug("serviceInstanceId: " + serviceInstanceId)
242 //check the e2e slice status
244 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business()
245 .customer(globalSubscriberId)
246 .serviceSubscription(subscriptionServiceType)
247 .serviceInstance(serviceInstanceId))
249 AAIResultWrapper wrapper = client.get(uri, NotFoundException.class)
250 Optional<ServiceInstance> si = wrapper.asBean(ServiceInstance.class)
251 ServiceInstance serviceInstance = si.orElseThrow()
253 boolean isContinue = handleOperation(customerInfo, serviceInstance)
254 execution.setVariable("isContinue", isContinue)
255 customerInfo.setSnssai(serviceInstance.getEnvironmentContext())
257 execution.setVariable("customerInfo", customerInfo)
258 execution.setVariable("ssInstance", serviceInstance)
259 execution.setVariable("ssiUri", uri)
260 } catch (BpmnError e) {
262 } catch (Exception ex) {
263 execution.setVariable("isContinue", "false")
264 msg = "Exception in org.onap.so.bpmn.common.scripts.CompleteMsoProcess.CheckAAIOrchStatus, " +
265 "Requested e2eservice does not exist: " + ex.getMessage()
267 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
270 logger.debug(Prefix + "CheckAAIOrchStatus Exit")
273 static boolean handleOperation(CustomerInfo customerInfo, ServiceInstance serviceInstance) {
274 OperationType operationType = customerInfo.operationType
275 OrchestrationStatusEnum status = OrchestrationStatusEnum.getStatus(Objects.requireNonNull(
276 serviceInstance.getOrchestrationStatus()))
278 return ((OrchestrationStatusEnum.ACTIVATED == status && OperationType.DEACTIVATE == operationType)
279 || (OrchestrationStatusEnum.DEACTIVATED == status && OperationType.ACTIVATE == operationType))
282 void checkAAIOrchStatusOfAllocates(DelegateExecution execution) {
283 logger.debug(Prefix + "CheckAAIOrchStatus Start")
284 CustomerInfo customerInfo = execution.getVariable("customerInfo") as CustomerInfo
286 String serviceInstanceId = customerInfo.serviceInstanceId
287 String globalSubscriberId = customerInfo.globalSubscriberId
288 String subscriptionServiceType = customerInfo.subscriptionServiceType
290 logger.debug("serviceInstanceId: " + serviceInstanceId)
292 //check the NSI is exist or the status of NSI is active or de-active
295 //get the allotted-resources by e2e slice id
296 AAIPluralResourceUri uriAllotted = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business()
297 .customer(globalSubscriberId)
298 .serviceSubscription(subscriptionServiceType)
299 .serviceInstance(serviceInstanceId)
303 AAIResultWrapper wrapperAllotted = client.get(uriAllotted, NotFoundException.class)
304 Optional<AllottedResources> allAllotted = wrapperAllotted.asBean(AllottedResources.class)
306 AllottedResources allottedResources = allAllotted.get()
307 List<AllottedResource> AllottedResourceList = allottedResources.getAllottedResource()
308 if (AllottedResourceList.isEmpty()) {
309 execution.setVariable("isContinue", "false")
310 exceptionUtil.buildAndThrowWorkflowException(execution, 2500,
311 "allottedResources in aai is empty")
313 AllottedResource ar = AllottedResourceList.first()
314 String relatedLink = ar.getRelationshipList().getRelationship().first().getRelatedLink()
315 String nsiServiceId = relatedLink.substring(relatedLink.lastIndexOf("/") + 1, relatedLink.length())
316 customerInfo.setNsiId(nsiServiceId)
317 execution.setVariable("customerInfo", customerInfo)
318 logger.info("the NSI ID is:" + nsiServiceId)
319 } catch (BpmnError e) {
321 } catch (Exception ex) {
322 logger.info("NSI Service doesnt exist")
323 execution.setVariable("isContinue", "false")
324 msg = "Exception in org.onap.so.bpmn.common.scripts.CompleteMsoProcess.CheckAAIOrchStatus " + ex.getMessage()
326 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
328 logger.debug(Prefix + "CheckAAIOrchStatus Exit")
331 void checkAAIOrchStatusOfNSI(DelegateExecution execution) {
333 logger.debug(Prefix + "CheckAAIOrchStatus Start")
334 CustomerInfo customerInfo = execution.getVariable("customerInfo") as CustomerInfo
336 String globalSubscriberId = customerInfo.globalSubscriberId
337 String subscriptionServiceType = customerInfo.subscriptionServiceType
338 String nsiServiceId = customerInfo.getNsiId()
340 logger.debug("network slice instance id: " + nsiServiceId)
342 //check the NSI is exist or the status of NSI is active or de-active
344 //Query nsi by nsi id
346 //get the NSI id by e2e slice id
347 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business()
348 .customer(globalSubscriberId)
349 .serviceSubscription(subscriptionServiceType)
350 .serviceInstance(nsiServiceId))
352 AAIResultWrapper wrapper = client.get(uri, NotFoundException.class)
353 Optional<ServiceInstance> si = wrapper.asBean(ServiceInstance.class)
355 ServiceInstance nsInstance = si.get()
356 if (!"nsi".equalsIgnoreCase(nsInstance.getServiceRole().toLowerCase())) {
357 logger.info("the service id" + nsInstance.getServiceInstanceId() + "is " +
358 nsInstance.getServiceRole())
359 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
361 execution.setVariable("nsInstance", nsInstance)
362 execution.setVariable("nsiUri", uri)
363 boolean isContinue = handleOperation(customerInfo, nsInstance)
364 execution.setVariable("isContinue", isContinue)
366 } catch (BpmnError e) {
368 } catch (Exception ex) {
369 logger.info("NSI Service doesnt exist")
370 execution.setVariable("isActivate", "false")
371 execution.setVariable("isContinue", "false")
372 msg = "Exception in org.onap.so.bpmn.common.scripts.CompleteMsoProcess.CheckAAIOrchStatus " + ex.getMessage()
374 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
376 logger.debug(Prefix + "CheckAAIOrchStatus Exit")
379 void prepareActivation(DelegateExecution execution) {
380 logger.debug(Prefix + "prepareActivation Start")
382 CustomerInfo customerInfo = execution.getVariable("customerInfo") as CustomerInfo
383 String globalSubscriberId = customerInfo.globalSubscriberId
384 String subscriptionServiceType = customerInfo.subscriptionServiceType
386 logger.debug(" ***** prepare active NSI/AN/CN/TN slice ***** ")
388 Queue<NssInstance> nssInstances = new LinkedList<>()
389 ServiceInstance nsInstance =
390 execution.getVariable("nsInstance") as ServiceInstance
392 //get the TN NSSI id by NSI id, active NSSI TN slicing
393 List<Relationship> relatedList = nsInstance.getRelationshipList().getRelationship()
394 for (Relationship relationship : relatedList) {
395 String relatedTo = relationship.getRelatedTo()
396 if (!"service-instance".equalsIgnoreCase(relatedTo)) {
399 String relatioshipurl = relationship.getRelatedLink()
400 String nssiserviceid = relatioshipurl.substring(relatioshipurl.lastIndexOf("/") + 1,
401 relatioshipurl.length())
403 AAIResourceUri nsiUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business()
404 .customer(globalSubscriberId)
405 .serviceSubscription(subscriptionServiceType)
406 .serviceInstance(nssiserviceid))
407 if (!client.exists(nsiUri)) {
408 exceptionUtil.buildAndThrowWorkflowException(execution, 2500,
409 "Service Instance was not found in aai")
411 AAIResultWrapper wrapper01 = client.get(nsiUri, NotFoundException.class)
412 Optional<ServiceInstance> nssiSi = wrapper01.asBean(ServiceInstance.class)
413 nssiSi.ifPresent(new Consumer<ServiceInstance>() {
415 void accept(ServiceInstance instance) {
416 String env = Objects.requireNonNull(instance.getEnvironmentContext())
417 NssInstance nssi = NssInstance.builder().nssiId(instance.getServiceInstanceId())
418 .modelInvariantId(instance.getModelInvariantId())
419 .modelVersionId(instance.getModelVersionId())
420 .networkType(NetworkType.fromString(env))
421 .operationType(customerInfo.operationType)
422 .snssai(customerInfo.snssai)
423 .serviceType(instance.getServiceType())
425 nssInstances.offer(nssi)
429 execution.setVariable("nssInstances", nssInstances)
430 execution.setVariable("nssInstanceInfos", nssInstances)
431 } catch (Exception e) {
432 String msg = "Requested service does not exist:" + e.getMessage()
433 logger.info("Service doesnt exist")
434 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
437 logger.debug(Prefix + "prepareActivation Exit")
440 void isOperationFinished(DelegateExecution execution) {
441 Queue<NssInstance> nssInstances = execution.getVariable("nssInstances") as Queue<NssInstance>
442 if (nssInstances.isEmpty()) {
443 execution.setVariable("isOperationFinished", "true")
447 def updateStatusSNSSAIandNSIandNSSI = { DelegateExecution execution ->
448 logger.debug(Prefix + "updateStatusSNSSAIandNSIandNSSI Start")
449 logger.debug(" ***** update SNSSAI NSI NSSI slicing ***** ")
450 ServiceInstance ssInstance = execution.getVariable("ssInstance") as ServiceInstance
451 AAIResourceUri ssUri = execution.getVariable("ssiUri") as AAIResourceUri
453 CustomerInfo customerInfo = execution.getVariable("customerInfo") as CustomerInfo
454 OperationType operationType = customerInfo.operationType
456 updateStratus(execution, ssInstance, operationType, ssUri)
458 ServiceInstance nsInstance = execution.getVariable("nsInstance") as ServiceInstance
459 AAIResourceUri nsiUri = execution.getVariable("nsiUri") as AAIResourceUri
461 updateStratus(execution, nsInstance, operationType, nsiUri)
464 logger.debug(Prefix + "updateStatusSNSSAIandNSIandNSSI Exit")
467 void updateStratus(DelegateExecution execution, ServiceInstance serviceInstance,
468 OperationType operationType, AAIResourceUri uri) {
470 logger.debug(Prefix + "updateStratus Start")
473 serviceInstance.setOrchestrationStatus()
474 if (OperationType.ACTIVATE == operationType) {
475 serviceInstance.setOrchestrationStatus(OrchestrationStatusEnum.ACTIVATED.getValue())
477 serviceInstance.setOrchestrationStatus(OrchestrationStatusEnum.DEACTIVATED.getValue())
479 client.update(uri, serviceInstance)
480 } catch (Exception e) {
481 logger.info("Service is already in active state")
482 String msg = "Service is already in active state, " + e.getMessage()
483 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
486 logger.debug(Prefix + "updateStratus Exit")
489 def prepareCompletionRequest = { DelegateExecution execution ->
490 logger.debug(Prefix + "prepareCompletionRequest Start")
491 CustomerInfo customerInfo = execution.getVariable("customerInfo") as CustomerInfo
492 String serviceId = customerInfo.getServiceInstanceId()
493 String operationId = customerInfo.getOperationId()
494 String userId = customerInfo.getGlobalSubscriberId()
496 String result = "finished"
497 String progress = "100"
499 String operationContent = "action finished success"
500 String operationType = customerInfo.operationType.getType()
502 OperationStatus initStatus = new OperationStatus()
503 initStatus.setServiceId(serviceId)
504 initStatus.setOperationId(operationId)
505 initStatus.setOperation(operationType)
506 initStatus.setUserId(userId)
507 initStatus.setResult(result)
508 initStatus.setProgress(progress)
509 initStatus.setReason(reason)
510 initStatus.setOperationContent(operationContent)
512 requestDBUtil.prepareUpdateOperationStatus(execution, initStatus)
514 logger.debug(Prefix + "prepareCompletionRequest Exit")