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.camunda.bpm.engine.delegate.BpmnError
 
  23 import org.camunda.bpm.engine.delegate.DelegateExecution
 
  24 import org.onap.aai.domain.yang.AllottedResource
 
  25 import org.onap.aai.domain.yang.AllottedResources
 
  26 import org.onap.aai.domain.yang.Relationship
 
  27 import org.onap.aai.domain.yang.ServiceInstance
 
  28 import org.onap.aaiclient.client.aai.AAIObjectName
 
  29 import org.onap.aaiclient.client.aai.entities.AAIResultWrapper
 
  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.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder.Types
 
  34 import org.onap.logging.filter.base.ONAPComponents
 
  35 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor
 
  36 import org.onap.so.bpmn.common.scripts.ExceptionUtil
 
  37 import org.onap.so.bpmn.common.scripts.OofUtils
 
  38 import org.onap.so.bpmn.core.UrnPropertiesReader
 
  39 import org.onap.so.client.HttpClient
 
  40 import org.onap.so.client.HttpClientFactory
 
  41 import org.slf4j.Logger
 
  42 import org.slf4j.LoggerFactory
 
  44 import javax.ws.rs.NotFoundException
 
  45 import javax.ws.rs.core.Response
 
  47 import static org.apache.commons.lang3.StringUtils.isBlank
 
  50  * This groovy class supports the <class>DoDeleteSliceService.bpmn</class> process.
 
  53  * @param - msoRequestId
 
  54  * @param - globalSubscriberId - O
 
  55  * @param - subscriptionServiceType - O
 
  56  * @param - serviceInstanceId
 
  59 class DoDeleteSliceService extends AbstractServiceTaskProcessor {
 
  60     private final String PREFIX ="DoDeleteSliceService"
 
  61     ExceptionUtil exceptionUtil = new ExceptionUtil()
 
  62     OofUtils oofUtils = new OofUtils()
 
  63     private static final Logger LOGGER = LoggerFactory.getLogger( DoDeleteSliceService.class)
 
  66     void preProcessRequest(DelegateExecution execution) {
 
  67         LOGGER.debug(" *****${PREFIX} preProcessRequest *****")
 
  71             //String requestId = execution.getVariable("msoRequestId")
 
  72             execution.setVariable("prefix",PREFIX)
 
  75             //requestDetails.subscriberInfo. for AAI GET & PUT
 
  76              execution.getVariable("globalSubscriberId") ?: execution.setVariable("globalSubscriberId", "")
 
  78             //requestDetails.requestParameters. for AAI PUT
 
  79             execution.getVariable("serviceType") ?: execution.setVariable("serviceType", "")
 
  81             //Generated in parent for AAI PUT
 
  82             String serviceInstanceId = execution.getVariable("serviceInstanceId")
 
  83             if (isBlank(serviceInstanceId)){
 
  84                 msg = "Input serviceInstanceId is null"
 
  86                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
 
  88         } catch (BpmnError e) {
 
  90         } catch (Exception ex){
 
  91             msg = "Exception in preProcessRequest " + ex.getMessage()
 
  93             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
 
  95         LOGGER.debug("*****${PREFIX} Exit preProcessRequest *****")
 
  99      * query E2ESliceService from AAI
 
 103     void queryServiceProfileFromAAI(DelegateExecution execution)
 
 105         LOGGER.trace(" *****${PREFIX} Start queryE2ESliceSeriveFromAAI *****")
 
 106         String serviceInstanceId = execution.getVariable("serviceInstanceId")
 
 109         String errorMsg = "query e2e slice service from aai failed"
 
 110         AAIResultWrapper wrapper = queryAAI(execution, Types.SERVICE_INSTANCE, serviceInstanceId, errorMsg)
 
 111         Optional<ServiceInstance> si =wrapper.asBean(ServiceInstance.class)
 
 114             String snssai = si.get()?.getEnvironmentContext()
 
 115             execution.setVariable("snssai", snssai ?: "")
 
 116 //            ServiceProfiles serviceProfiles = si.get()?.getServiceProfiles()
 
 117 //            ServiceProfile serviceProfile = serviceProfiles.getServiceProfile().get(0)
 
 118 //            String serviceProfileId = serviceProfile ? serviceProfile.getProfileId() : ""
 
 119 //            execution.setVariable("serviceProfileId", serviceProfileId)
 
 120             List<ServiceInstance> sliceProfileList = []
 
 121             List<Relationship> relationshipList = si.get().getRelationshipList().getRelationship()
 
 122             for (Relationship relationship : relationshipList) {
 
 123                 String relatedTo = relationship.getRelatedTo()
 
 124                 if (relatedTo.toLowerCase() == "service-instance") {
 
 125                     String relatioshipurl = relationship.getRelatedLink()
 
 126                     String instanceId = relatioshipurl.substring(relatioshipurl.lastIndexOf("/") + 1, relatioshipurl.length())
 
 127                     AAIResultWrapper wrapper1 = queryAAI(execution, Types.SERVICE_INSTANCE, instanceId, errorMsg)
 
 128                     Optional<ServiceInstance> serviceInstance = wrapper1.asBean(ServiceInstance.class)
 
 129                     if (serviceInstance.isPresent()) {
 
 130                         ServiceInstance instance = serviceInstance.get()
 
 131                         if ("slice-profile".equalsIgnoreCase(instance.getServiceRole())) {
 
 132                             sliceProfileList.add(instance)
 
 137             execution.setVariable("sliceProfileList",sliceProfileList)
 
 138             LOGGER.info("serviceInstanceId: ${serviceInstanceId}, snssai: ${snssai}, sliceProfileList: ${sliceProfileList}")
 
 140         LOGGER.trace(" *****${PREFIX} Exit queryE2ESliceSeriveFromAAI *****")
 
 144             String msg = "query E2E slice service from aai failed! cause-"+any.getCause()
 
 145             LOGGER.error(any.printStackTrace())
 
 146             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg);
 
 151      * get allotted resource from AAI
 
 155     void getAllottedResFromAAI(DelegateExecution execution)
 
 157         LOGGER.trace(" *****${PREFIX} Start getAllottedResFromAAI *****")
 
 158         String serviceInstanceId = execution.getVariable("serviceInstanceId")
 
 161             String errorMsg = "query allotted resource from aai failed."
 
 162             AAIResultWrapper wrapper = queryAAI(execution, Types.ALLOTTED_RESOURCE, serviceInstanceId, errorMsg)
 
 163             Optional<AllottedResources> ars = wrapper?.asBean(AllottedResources.class)
 
 164             if(ars.isPresent() && ars.get().getAllottedResource())
 
 166                 List<AllottedResource> allottedResourceList = ars.get().getAllottedResource()
 
 167                 AllottedResource ar = allottedResourceList.first()
 
 168                 String relatedLink = ar?.getRelationshipList()?.getRelationship()?.first()?.getRelatedLink()
 
 169                 String nsiId = relatedLink ? relatedLink.substring(relatedLink.lastIndexOf("/") + 1,relatedLink.length()) : ""
 
 170                 execution.setVariable("nsiId", nsiId)
 
 171                 LOGGER.info("serviceInstanceId: ${serviceInstanceId}, nsiId:${nsiId}")
 
 177         catch (Exception ex){
 
 178             String msg = "Exception in getAllottedResFromAAI " + ex.getMessage()
 
 180             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
 
 182         LOGGER.trace(" *****${PREFIX} Exit getAllottedResFromAAI *****")
 
 186      * get nsi service instance from aai
 
 190     void getNSIFromAAI(DelegateExecution execution)
 
 192         LOGGER.trace(" *****${PREFIX} Start getNSIFromAAI *****")
 
 193         String nsiId = execution.getVariable("nsiId")
 
 194         List<String> nssiIdList = getNSSIIdList(execution, nsiId)
 
 195         String msg = "nsiId: ${nsiId}, nssiIdList:"
 
 196         msg+= nssiIdList.join(",")
 
 198         execution.setVariable("nssiIdList", nssiIdList)
 
 199         LOGGER.trace(" *****${PREFIX} Exit getNSIFromAAI *****")
 
 202      * Get NSSI Id from AAI
 
 207     private List<String> getNSSIIdList(DelegateExecution execution, String nsiId){
 
 208         List<String> nssiIdList = []
 
 212             String errorMsg = "query nssi from aai failed."
 
 213             AAIResultWrapper wrapper = queryAAI(execution, Types.SERVICE_INSTANCE, nsiId, errorMsg)
 
 214             Optional<ServiceInstance> si = wrapper.asBean(ServiceInstance.class)
 
 217                 List<Relationship> relationshipList = si.get().getRelationshipList()?.getRelationship()
 
 218                 for (Relationship relationship : relationshipList)
 
 220                     String relatedTo = relationship.getRelatedTo()
 
 221                     if (relatedTo == "service-instance")
 
 223                         String relatedLink = relationship.getRelatedLink()?:""
 
 224                         String instanceId = relatedLink ? relatedLink.substring(relatedLink.lastIndexOf("/") + 1,relatedLink.length()) : ""
 
 225                         AAIResultWrapper wrapper1 = queryAAI(execution, Types.SERVICE_INSTANCE, instanceId, errorMsg)
 
 226                         Optional<ServiceInstance> serviceInstance = wrapper1.asBean(ServiceInstance.class)
 
 228                         if (serviceInstance.isPresent()) {
 
 229                             ServiceInstance instance = serviceInstance.get()
 
 230                             if ("nssi".equalsIgnoreCase(instance.getServiceRole())) {
 
 231                                 nssiId = instance.getServiceInstanceId()
 
 232                                 nssiIdList.add(nssiId)
 
 242         catch (Exception ex){
 
 243             String msg = "Exception in getNSIFromAAI " + ex.getMessage()
 
 245             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
 
 251      * get nssi service from AAI
 
 255     void getNSSIListFromAAI(DelegateExecution execution)
 
 257         LOGGER.trace("*****${PREFIX} Start getNSSIListFromAAI *****")
 
 258         List<String> nssiIdList = execution.getVariable("nssiIdList")
 
 259         List<ServiceInstance> nssiInstanceList = []
 
 260         String errorMsg = "query nssi list from aai failed"
 
 261         for(String nssiId : nssiIdList)
 
 263             AAIResultWrapper wrapper = queryAAI(execution, Types.SERVICE_INSTANCE, nssiId, errorMsg)
 
 264             Optional<ServiceInstance> si =wrapper.asBean(ServiceInstance.class)
 
 267                 nssiInstanceList.add(si.get())
 
 270         int size = nssiInstanceList.size()
 
 271         int proportion = size >0 ?((90/size) as int) : 90
 
 272         execution.setVariable("nssiInstanceList", nssiInstanceList)
 
 273         execution.setVariable("currentNSSIIndex", 0)
 
 274         execution.setVariable("proportion", proportion)
 
 275         String msg ="nssiInstanceList size: ${nssiInstanceList.size()}, proportion:${proportion}"
 
 277         LOGGER.trace(" *****${PREFIX} Exit getNSSIListFromAAI *****")
 
 284     void getCurrentNSSI(DelegateExecution execution)
 
 286         LOGGER.trace(" *****${PREFIX} Start getCurrentNSSI *****")
 
 287         List<ServiceInstance> nssiInstanceList = execution.getVariable("nssiInstanceList")
 
 288         List<ServiceInstance> sliceProfileList = execution.getVariable("sliceProfileList")
 
 289         int currentIndex = execution.getVariable("currentNSSIIndex") as int
 
 290         String profileInstId = ""
 
 291         ServiceInstance nssi = nssiInstanceList?.get(currentIndex)
 
 292         List<Relationship> relationshipList = nssi.getRelationshipList()?.getRelationship()
 
 293         for(ServiceInstance sliceProfileInstance : sliceProfileList) {
 
 294             for (Relationship relationship : relationshipList) {
 
 295                 String relatedTo = relationship.getRelatedTo()
 
 296                 if (relatedTo == "service-instance"){
 
 297                     String relatedLink = relationship.getRelatedLink()?:""
 
 298                     String instanceId = relatedLink ? relatedLink.substring(relatedLink.lastIndexOf("/") + 1,relatedLink.length()) : ""
 
 299                     if(instanceId.equals(sliceProfileInstance.getServiceInstanceId())){
 
 300                         profileInstId = sliceProfileInstance.getServiceInstanceId()
 
 310         //@TODO Temp begin*******************
 
 311 //        AAIPluralResourceUri resourceUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(execution.getVariable("globalSubscriberId")).serviceSubscription(execution.getVariable("serviceType")).serviceInstance(profileInstId).sliceProfiles())
 
 312 //        AAIResultWrapper wrapper = getAAIClient().get(resourceUri, NotFoundException.class)
 
 313 //        Optional<SliceProfiles> sliceProfilesOpt =wrapper.asBean(SliceProfiles.class)
 
 314 //        SliceProfiles sliceProfiles
 
 315 //        String sliceProfileId
 
 316 //        if(sliceProfilesOpt.isPresent()){
 
 317 //            sliceProfiles = sliceProfilesOpt.get()
 
 318 //            org.onap.aai.domain.yang.SliceProfile sliceProfile = sliceProfiles.getSliceProfile().get(0)
 
 319 //            sliceProfileId = sliceProfile ? sliceProfile.getProfileId() : ""
 
 321         //@TODO Temp end*******************
 
 323         def currentNSSI = [:]
 
 324         currentNSSI['nssiServiceInstanceId'] = nssi?.getServiceInstanceId()
 
 325         currentNSSI['modelInvariantId'] = nssi?.getModelInvariantId()
 
 326         currentNSSI['modelVersionId'] = nssi?.getModelVersionId()
 
 327         currentNSSI['nssiName'] = nssi?.getServiceInstanceName()
 
 328         currentNSSI['sST'] = nssi?.getServiceType()
 
 329         currentNSSI['PLMNIdList'] = nssi?.getServiceInstanceLocationId()
 
 332         currentNSSI['profileId'] =  profileInstId
 
 333 //        currentNSSI['profileId'] =  sliceProfileId
 
 334         currentNSSI['snssai'] = execution.getVariable("snssai") ?: ""
 
 335         currentNSSI['nsiServiceInstanceId'] = execution.getVariable("nsiId") ?: ""
 
 336         currentNSSI['operationId'] = execution.getVariable("operationId") ?: ""
 
 337         currentNSSI['e2eServiceInstanceId'] = execution.getVariable("serviceInstanceId") ?: ""
 
 338         currentNSSI['msoRequestId'] = execution.getVariable("msoRequestId") ?: ""
 
 339         currentNSSI['globalSubscriberId'] = execution.getVariable("globalSubscriberId") ?: ""
 
 340         currentNSSI['serviceType'] = execution.getVariable("serviceType") ?: ""
 
 341         currentNSSI['serviceModelInfo'] = execution.getVariable("serviceModelInfo") ?: ""
 
 342         currentNSSI['proportion'] = (execution.getVariable("proportion") as int)*(currentIndex+1)
 
 343         execution.setVariable("currentNSSI", currentNSSI)
 
 344         String msg = "Now we deal with nssiServiceInstanceId: ${currentNSSI['nssiServiceInstanceId']}, current Index: ${currentIndex}, current proportion:${currentNSSI['proportion']}"
 
 346         LOGGER.trace(" *****${PREFIX} Exit getCurrentNSSI *****")
 
 353     void parseNextNSSI(DelegateExecution execution)
 
 355         LOGGER.trace(" *****${PREFIX} Start parseNextNSSI *****")
 
 356         if(execution.getVariable("WorkflowException") != null){
 
 357             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, "current job failure!")
 
 359         def currentIndex = execution.getVariable("currentNSSIIndex")
 
 360         List<ServiceInstance> nssiInstanceList = execution.getVariable("nssiInstanceList")
 
 361         def nextIndex = ++currentIndex
 
 362         LOGGER.info("nextIndex: ${nextIndex}")
 
 363         if(nextIndex >= nssiInstanceList.size()){
 
 364             execution.setVariable("isAllNSSIFinished", "true")
 
 366             execution.setVariable("isAllNSSIFinished", "false")
 
 367             execution.setVariable("currentNSSIIndex", nextIndex)
 
 369         LOGGER.trace(" *****${PREFIX} Exit parseNextNSSI *****")
 
 375      * @param aaiObjectName
 
 377      * @return AAIResultWrapper
 
 379     private AAIResultWrapper queryAAI(DelegateExecution execution, AAIObjectName aaiObjectName, String instanceId, String errorMsg)
 
 381         LOGGER.trace(" *****${PREFIX} Start queryAAI *****")
 
 382         String globalSubscriberId = execution.getVariable("globalSubscriberId")
 
 383         String serviceType = execution.getVariable("serviceType")
 
 385         org.onap.aaiclient.client.generated.fluentbuilders.ServiceInstance serviceInstanceType = AAIFluentTypeBuilder.business().customer(globalSubscriberId).serviceSubscription(serviceType).serviceInstance(instanceId)
 
 387         if (aaiObjectName == Types.ALLOTTED_RESOURCE) {
 
 388             type = serviceInstanceType.allottedResources()
 
 389         } else if (aaiObjectName == Types.SLICE_PROFILES) {
 
 390             type = serviceInstanceType.sliceProfiles()
 
 392             type = serviceInstanceType
 
 394         def uri = AAIUriFactory.createResourceUri(type)
 
 395         if (!getAAIClient().exists(uri)) {
 
 396             exceptionUtil.buildAndThrowWorkflowException(execution, 2500, errorMsg)
 
 398         AAIResultWrapper wrapper = getAAIClient().get(uri, NotFoundException.class)
 
 399         LOGGER.trace(" *****${PREFIX} Exit queryAAI *****")
 
 403     void terminateNSIQuery(DelegateExecution execution)
 
 405         LOGGER.debug("Start terminateNSIQuery")
 
 410         String requestId = execution.getVariable("msoRequestId")
 
 411         String nxlId = currentNSSI['nsiServiceInstanceId']
 
 412         String nxlType = "NSI"
 
 413         String messageType = "nsiTerminationResponse"
 
 414         String serviceInstanceId = execution.getVariable("serviceInstanceId")
 
 417         String basicAuth = UrnPropertiesReader.getVariable("mso.oof.auth", execution)
 
 418         String msokey = UrnPropertiesReader.getVariable("mso.msoKey", execution)
 
 420         String basicAuthValue = utils.encrypt(basicAuth, msokey)
 
 421         if (basicAuthValue != null) {
 
 422             LOGGER.debug( "Obtained BasicAuth username and password for OOF: " + basicAuthValue)
 
 424                 authHeader = utils.getBasicAuth(basicAuthValue, msokey)
 
 425                 execution.setVariable("BasicAuthHeaderValue", authHeader)
 
 426             } catch (Exception ex) {
 
 427                 LOGGER.debug( "Unable to encode username and password string: " + ex)
 
 428                 exceptionUtil.buildAndThrowWorkflowException(execution, 401, "Internal Error - Unable to " +
 
 429                         "encode username and password string")
 
 432             LOGGER.debug( "Unable to obtain BasicAuth - BasicAuth value null")
 
 433             exceptionUtil.buildAndThrowWorkflowException(execution, 401, "Internal Error - BasicAuth " +
 
 437         URL requestUrl = new URL(oofUrl + "/api/oof/terminate/nxi/v1")
 
 438         String oofRequest = oofUtils.buildTerminateNxiRequest(requestId, nxlId, nxlType, messageType, serviceInstanceId)
 
 439         HttpClient httpClient = new HttpClientFactory().newJsonClient(requestUrl, ONAPComponents.OOF)
 
 440         httpClient.addAdditionalHeader("Authorization", authHeader)
 
 441         Response httpResponse = httpClient.post(oofRequest)
 
 443         int responseCode = httpResponse.getStatus()
 
 444         LOGGER.debug("OOF sync response code is: " + responseCode)
 
 446         if(responseCode != 200){
 
 447             exceptionUtil.buildAndThrowWorkflowException(execution, responseCode, "Received a Bad Sync Response from OOF.")
 
 450             Map<String, String> resMap = httpResponse.readEntity(Map.class)
 
 451             boolean terminateResponse = resMap.get("terminateResponse")
 
 452             execution.setVariable("terminateNSI", terminateResponse)
 
 453         } catch (Exception ex) {
 
 454             LOGGER.debug( "Failed to get terminate Response suggested by OOF.")
 
 455             exceptionUtil.buildAndThrowWorkflowException(execution, 401, "Failed to get terminate Response suggested by OOF.")
 
 457         LOGGER.debug("Finish terminateNSIQuery")
 
 462      * If no nssi,delete NSI from AAI
 
 465     void deleteNSIInstance(DelegateExecution execution){
 
 466         def currentNSSI = execution.getVariable("currentNSSI")
 
 467         def nsiId = currentNSSI['nsiServiceInstanceId']
 
 468         List<String> nssiIdList = getNSSIIdList(execution, nsiId)
 
 471             if(0 == nssiIdList.size()){
 
 472                 AAIResourceUri serviceInstanceUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(execution.getVariable("globalSubscriberId")).serviceSubscription(execution.getVariable("serviceType")).serviceInstance(nsiId))
 
 473                 getAAIClient().delete(serviceInstanceUri)
 
 475         } catch (Exception ex) {
 
 476             LOGGER.debug( "Failed to delete NSI instance.")
 
 477             exceptionUtil.buildAndThrowWorkflowException(execution, 401, "Failed to delete NSI instance.")