2  * ============LICENSE_START=======================================================
 
   4  * ================================================================================
 
   5  * Copyright (C) 2020  Telecom Italia
 
   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
 
  23 import com.fasterxml.jackson.databind.ObjectMapper
 
  24 import org.camunda.bpm.engine.delegate.DelegateExecution
 
  25 import org.onap.aai.domain.yang.v19.AllottedResource
 
  26 import org.onap.aai.domain.yang.v19.AllottedResources
 
  27 import org.onap.aai.domain.yang.v19.ServiceInstance
 
  28 import org.onap.aai.domain.yang.v19.SliceProfile
 
  29 import org.onap.aai.domain.yang.v19.SliceProfiles
 
  30 import org.onap.aaiclient.client.aai.AAIResourcesClient
 
  31 import org.onap.aaiclient.client.aai.entities.AAIEdgeLabel
 
  32 import org.onap.aaiclient.client.aai.entities.AAIResultWrapper
 
  33 import org.onap.aaiclient.client.aai.entities.Relationships
 
  34 import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri
 
  35 import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory
 
  36 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder
 
  37 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder.Types
 
  38 import org.onap.so.bpmn.common.scripts.ExceptionUtil
 
  39 import org.onap.so.bpmn.common.scripts.MsoUtils
 
  40 import org.onap.so.bpmn.common.scripts.RequestDBUtil
 
  41 import org.onap.so.bpmn.core.json.JsonUtils
 
  42 import org.slf4j.Logger
 
  43 import org.slf4j.LoggerFactory
 
  45 import static org.apache.commons.lang3.StringUtils.isAllLowerCase
 
  46 import static org.apache.commons.lang3.StringUtils.isBlank
 
  48 class DoModifyCoreNSSI extends DoCommonCoreNSSI {
 
  50     private final String PREFIX ="DoModifyCoreNSSI"
 
  51     private final String ACTION = "Modify"
 
  53     private ExceptionUtil exceptionUtil = new ExceptionUtil()
 
  54     private RequestDBUtil requestDBUtil = new RequestDBUtil()
 
  55     private MsoUtils utils = new MsoUtils()
 
  56     private JsonUtils jsonUtil = new JsonUtils()
 
  58     private static final Logger LOGGER = LoggerFactory.getLogger( DoModifyCoreNSSI.class)
 
  62     void preProcessRequest(DelegateExecution execution) {
 
  63         LOGGER.debug("${getPrefix()} Start preProcessRequest")
 
  65         super.preProcessRequest(execution)
 
  67         String modifyAction = jsonUtil.getJsonValue(execution.getVariable("sliceParams"), "modifyAction")
 
  68         if (isBlank(modifyAction)) {
 
  69             String msg = "modifyAction is mandatory parameter"
 
  70             exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
 
  73             String createSliceProfileInstance = ""
 
  74             if(modifyAction.equals("allocate")) { // In case Slice Profile should be created
 
  75                 createSliceProfileInstance = "true"
 
  77             else if(modifyAction.equals("deallocate")) { // In case Slice Profile should be created
 
  78                 createSliceProfileInstance = "false"
 
  81                 String msg = "Value of modifyAction parameter should be either allocate or deallocate"
 
  82                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
 
  85             execution.setVariable("isCreateSliceProfileInstance", createSliceProfileInstance)
 
  88         execution.setVariable("operationType", "MODIFY")
 
  90         LOGGER.debug("${getPrefix()} Exit preProcessRequest")
 
  95      * Prepares Slice Profile
 
  97      * @return SLice Profile
 
  99     SliceProfile prepareSliceProfile(DelegateExecution execution) {
 
 100         LOGGER.debug("${PREFIX} Start prepareSliceProfile")
 
 102         def currentNSSI = execution.getVariable("currentNSSI")
 
 104         String givenSliceProfileId = currentNSSI['sliceProfileId'] //UUID.randomUUID().toString()
 
 105         Map<String,Object> sliceProfileMap = new ObjectMapper().readValue(currentNSSI['sliceProfile'], Map.class)
 
 107         SliceProfile sliceProfile = new SliceProfile()
 
 108         sliceProfile.setServiceAreaDimension("")
 
 109         sliceProfile.setPayloadSize(0)
 
 110         sliceProfile.setJitter(0)
 
 111         sliceProfile.setSurvivalTime(0)
 
 112         sliceProfile.setExpDataRate(0)
 
 113         sliceProfile.setTrafficDensity(0)
 
 114         sliceProfile.setConnDensity(0)
 
 115         sliceProfile.setSNssai(currentNSSI['S-NSSAI'])
 
 117         if(sliceProfileMap.get("expDataRateUL") != null) {
 
 118             sliceProfile.setExpDataRateUL(Integer.parseInt(sliceProfileMap.get("expDataRateUL").toString()))
 
 121         if(sliceProfileMap.get("expDataRateDL") != null) {
 
 122             sliceProfile.setExpDataRateDL(Integer.parseInt(sliceProfileMap.get("expDataRateDL").toString()))
 
 125         if(sliceProfileMap.get("activityFactor") != null) {
 
 126             sliceProfile.setActivityFactor(Integer.parseInt(sliceProfileMap.get("activityFactor").toString()))
 
 129         if(sliceProfileMap.get("resourceSharingLevel") != null) {
 
 130             sliceProfile.setResourceSharingLevel(sliceProfileMap.get("resourceSharingLevel").toString())
 
 133         if(sliceProfileMap.get("uEMobilityLevel") != null) {
 
 134             sliceProfile.setUeMobilityLevel(sliceProfileMap.get("uEMobilityLevel").toString())
 
 137         if(sliceProfileMap.get("coverageAreaTAList") != null) {
 
 138             sliceProfile.setCoverageAreaTAList(sliceProfileMap.get("coverageAreaTAList").toString())
 
 141         if(sliceProfileMap.get("maxNumberOfUEs") != null) {
 
 142             sliceProfile.setMaxNumberOfUEs(Integer.parseInt(sliceProfileMap.get("maxNumberOfUEs").toString()))
 
 145         if(sliceProfileMap.get("latency") != null) {
 
 146             sliceProfile.setLatency(Integer.parseInt(sliceProfileMap.get("latency").toString()))
 
 149         sliceProfile.setProfileId(givenSliceProfileId)
 
 150         sliceProfile.setE2ELatency(0)
 
 152         LOGGER.debug("${PREFIX} Exit prepareSliceProfile")
 
 159      * Prepares Slice Profile Instance
 
 161      * @return Slice Profile Instance
 
 163     ServiceInstance prepareSliceProfileInstance(DelegateExecution execution) {
 
 164         LOGGER.debug("${PREFIX} Start prepareSliceProfileInstance")
 
 166         def currentNSSI = execution.getVariable("currentNSSI")
 
 168         ServiceInstance sliceProfileInstance = new ServiceInstance()
 
 169         String sliceProfileInstanceId = UUID.randomUUID().toString()
 
 170         sliceProfileInstance.setServiceInstanceId(sliceProfileInstanceId)
 
 173         String sliceInstanceName = "sliceprofile_" + sliceProfileInstanceId
 
 174         sliceProfileInstance.setServiceInstanceName(sliceInstanceName)
 
 176         String serviceType = jsonUtil.getJsonValue(currentNSSI['sliceProfile'], "sST")
 
 177         sliceProfileInstance.setServiceType(serviceType)
 
 179         String serviceStatus = "deactivated"
 
 180         sliceProfileInstance.setOrchestrationStatus(serviceStatus)
 
 182         String serviceInstanceLocationid = jsonUtil.getJsonValue(currentNSSI['sliceProfile'], "pLMNIdList")
 
 183         sliceProfileInstance.setServiceInstanceLocationId(serviceInstanceLocationid)
 
 185         String serviceRole = "slice-profile-instance"
 
 186         sliceProfileInstance.setServiceRole(serviceRole)
 
 187         List<String> snssaiList = (List<String>)currentNSSI['S-NSSAIs']
 
 188         String snssai = snssaiList.get(0)
 
 190         sliceProfileInstance.setEnvironmentContext(snssai)
 
 191         sliceProfileInstance.setWorkloadContext("CN-NF")
 
 195         LOGGER.debug("${PREFIX} Exit prepareSliceProfileInstance")
 
 197         return sliceProfileInstance
 
 203      * Creates Slice Profile Instance
 
 206     void createSliceProfileInstance(DelegateExecution execution) {
 
 207         LOGGER.debug("${PREFIX} Start createSliceProfileInstance")
 
 209         def currentNSSI = execution.getVariable("currentNSSI")
 
 211         String globalSubscriberId = execution.getVariable("globalSubscriberId")
 
 212         String subscriptionServiceType = execution.getVariable("subscriptionServiceType")
 
 214         SliceProfile sliceProfile = prepareSliceProfile(execution)
 
 216         ServiceInstance sliceProfileInstance = prepareSliceProfileInstance(execution)
 
 218         SliceProfiles sliceProfiles = new SliceProfiles()
 
 219         sliceProfiles.getSliceProfile().add(sliceProfile)
 
 220         sliceProfileInstance.setSliceProfiles(sliceProfiles)
 
 223             AAIResourcesClient client = getAAIClient()
 
 224             AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(globalSubscriberId).serviceSubscription(subscriptionServiceType).
 
 225                                                                 serviceInstance(sliceProfileInstance.getServiceInstanceId()))
 
 226             client.create(uri, sliceProfileInstance)
 
 228             currentNSSI['createdSliceProfileInstanceId'] = sliceProfileInstance.getServiceInstanceId()
 
 229         } catch (Exception ex) {
 
 230             exceptionUtil.buildAndThrowWorkflowException(execution, 25000, "Exception occurred while Slice Profile create call:" + ex.getMessage())
 
 233         LOGGER.debug("${PREFIX} Exit createSliceProfileInstance")
 
 238      * Creates Allotted Resource
 
 240      * @return AllottedResource
 
 242     AllottedResource createAllottedResource(DelegateExecution execution) {
 
 243         LOGGER.debug("${PREFIX} Start createAllottedResource")
 
 245         def currentNSSI = execution.getVariable("currentNSSI")
 
 247         String globalSubscriberId = execution.getVariable("globalSubscriberId")
 
 248         String subscriptionServiceType = execution.getVariable("subscriptionServiceType")
 
 249         String sliceProfileInstanceId = currentNSSI['createdSliceProfileInstanceId']
 
 251         AllottedResource allottedResource = new AllottedResource()
 
 253         String allottedResourceId = UUID.randomUUID().toString()
 
 255         allottedResource.setId(allottedResourceId)
 
 257         // TO DO: No other info
 
 260             AAIResourcesClient client = getAAIClient()
 
 261             AAIResourceUri allottedResourceUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(globalSubscriberId).serviceSubscription(subscriptionServiceType).serviceInstance(sliceProfileInstanceId).allottedResource(allottedResourceId))
 
 263             client.create(allottedResourceUri, allottedResource)
 
 265             currentNSSI['allottedResourceUri'] = allottedResourceUri
 
 266         } catch (Exception ex) {
 
 267             exceptionUtil.buildAndThrowWorkflowException(execution, 25000, "Exception occurred while Allotted Resource create call:" + ex.getMessage())
 
 270         LOGGER.debug("${PREFIX} Exit createAllottedResource")
 
 272         return allottedResource
 
 278      * Creates Slice Profile association with NSSI
 
 281     void associateSliceProfileInstanceWithNSSI(DelegateExecution execution) {
 
 282         LOGGER.debug("${PREFIX} Start associateSliceProfileInstanceWithNSSI")
 
 284         def currentNSSI = execution.getVariable("currentNSSI")
 
 286         String nssiId = currentNSSI['nssiId']
 
 288         String sliceProfileInstanceId = currentNSSI['createdSliceProfileInstanceId']
 
 290         AAIResourcesClient client = getAAIClient()
 
 292         // Creates Allotted Resource
 
 293         AllottedResource allottedResource = createAllottedResource(execution)
 
 294         AAIResourceUri allottedResourceUri = (AAIResourceUri)currentNSSI['allottedResourceUri']
 
 296         // Associates Allotted Resource with Slice Profile Instance
 
 298             AAIResourceUri sliceProfileInstanceUri = AAIUriFactory.createResourceUri(Types.SERVICE_INSTANCE.getFragment(sliceProfileInstanceId))
 
 299             Optional<ServiceInstance> sliceProfileInstanceOpt = client.get(ServiceInstance.class, sliceProfileInstanceUri)
 
 300             if (sliceProfileInstanceOpt.isPresent()) {
 
 301              /*   ServiceInstance sliceProfileInstance = sliceProfileInstanceOpt.get()
 
 303                 AllottedResources allottedResources = sliceProfileInstance.getAllottedResources()
 
 304                 if(allottedResources == null) {
 
 305                     allottedResources = new AllottedResources()
 
 308                 allottedResources.getAllottedResource().add(allottedResource)
 
 309                 sliceProfileInstance.setAllottedResources(allottedResources)
 
 311                 client.update(sliceProfileInstanceUri, sliceProfileInstance) */
 
 313                 client.connect(sliceProfileInstanceUri, allottedResourceUri)
 
 316                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, "No slice profile instance found with id = " + sliceProfileInstanceId)
 
 319         } catch(Exception e){
 
 320             exceptionUtil.buildAndThrowWorkflowException(execution, 25000, "Exception occured while Slice Profile Instance update call: " + e.getMessage())
 
 324         // Associates NSSI with Allotted Resource
 
 326             AAIResourceUri nssiUri = AAIUriFactory.createResourceUri(Types.SERVICE_INSTANCE.getFragment(nssiId))
 
 327             client.connect(allottedResourceUri, nssiUri)
 
 328         } catch(Exception e){
 
 329             exceptionUtil.buildAndThrowWorkflowException(execution, 25000, "Exception occured while NSSI with Allotted Resource connect call: " + e.getMessage())
 
 332         LOGGER.debug("${PREFIX} Exit associateSliceProfileInstanceWithNSSI")
 
 337     void checkAssociatedProfiles(DelegateExecution execution, List<SliceProfile> associatedProfiles, ServiceInstance nssi) {
 
 338         LOGGER.debug("${PREFIX} Start checkAssociatedProfiles")
 
 340         LOGGER.debug("associatedProfiles == null = " + (associatedProfiles == null))
 
 341         if(associatedProfiles == null || associatedProfiles.isEmpty()) {
 
 342             String isCreateSliceProfileInstanceVar = execution.getVariable("isCreateSliceProfileInstance" )
 
 343             boolean isCreateSliceProfileInstance = Boolean.parseBoolean(isCreateSliceProfileInstanceVar)
 
 345             if(!isCreateSliceProfileInstance) { // New Slice Profile Instance should not be created
 
 346                 String msg = String.format("No associated profiles found for NSSI %s in AAI", nssi.getServiceInstanceId())
 
 348                 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, msg)
 
 352         LOGGER.debug("${PREFIX} Exit checkAssociatedProfiles")
 
 357      * Calculates a final list of S-NSSAI
 
 360     void calculateSNSSAI(DelegateExecution execution) {
 
 361         LOGGER.debug("${getPrefix()} Start calculateSNSSAI")
 
 363         def currentNSSI = execution.getVariable("currentNSSI")
 
 365         List<SliceProfile> associatedProfiles = (List<SliceProfile>)currentNSSI['associatedProfiles']
 
 367         String currentSNSSAI = currentNSSI['S-NSSAI']
 
 369         String givenSliceProfileId = currentNSSI['sliceProfileId']
 
 371         List<String> snssais = new ArrayList<>()
 
 373         String isCreateSliceProfileInstanceVar = execution.getVariable("isCreateSliceProfileInstance" )
 
 375         boolean isCreateSliceProfileInstance = Boolean.parseBoolean(isCreateSliceProfileInstanceVar)
 
 377         if(isCreateSliceProfileInstance) { // Slice Profile Instance has to be created
 
 378             for (SliceProfile associatedProfile : associatedProfiles) {
 
 379                 snssais.add(associatedProfile.getSNssai())
 
 382             snssais.add(currentSNSSAI)
 
 384         else { // Slice profile instance has to be deleted
 
 385             if(associatedProfiles != null) {
 
 386                 for (SliceProfile associatedProfile : associatedProfiles) {
 
 387                     if (!associatedProfile.getProfileId().equals(givenSliceProfileId)) { // not given profile id
 
 388                         LOGGER.debug("calculateSNSSAI: associatedProfile.getSNssai()" + associatedProfile.getSNssai())
 
 389                         snssais.add(associatedProfile.getSNssai())
 
 391                         currentNSSI['sliceProfileS-NSSAI'] = associatedProfile
 
 397         currentNSSI['S-NSSAIs'] = snssais
 
 399         LOGGER.debug("${getPrefix()} Exit calculateSNSSAI")
 
 403     private String getPrefix() {