2  * ============LICENSE_START=======================================================
 
   4  * ================================================================================
 
   5  * Copyright (C) 2020 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
 
  23 import com.fasterxml.jackson.databind.ObjectMapper
 
  24 import com.google.gson.JsonArray
 
  25 import com.google.gson.JsonObject
 
  26 import groovy.json.JsonSlurper
 
  27 import org.camunda.bpm.engine.delegate.BpmnError
 
  28 import org.camunda.bpm.engine.delegate.DelegateExecution
 
  29 import org.onap.aai.domain.yang.ServiceInstance
 
  30 import org.onap.aaiclient.client.aai.AAIObjectType
 
  31 import org.onap.aaiclient.client.aai.AAIResourcesClient
 
  32 import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri
 
  33 import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory
 
  34 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor
 
  35 import org.onap.so.bpmn.common.scripts.ExceptionUtil
 
  36 import org.onap.so.bpmn.common.scripts.RequestDBUtil
 
  37 import org.onap.so.bpmn.core.UrnPropertiesReader
 
  38 import org.onap.so.bpmn.core.domain.ServiceDecomposition
 
  39 import org.onap.so.bpmn.core.domain.ServiceProxy
 
  40 import org.onap.so.bpmn.core.json.JsonUtils
 
  41 import org.onap.so.db.request.beans.ResourceOperationStatus
 
  42 import org.slf4j.Logger
 
  43 import org.slf4j.LoggerFactory
 
  44 import org.springframework.web.util.UriUtils
 
  46 import static org.apache.commons.lang3.StringUtils.isBlank
 
  48 class TnAllocateNssi extends AbstractServiceTaskProcessor {
 
  49     String Prefix = "TNALLOC_"
 
  51     ExceptionUtil exceptionUtil = new ExceptionUtil()
 
  52     JsonUtils jsonUtil = new JsonUtils()
 
  53     RequestDBUtil requestDBUtil = new RequestDBUtil()
 
  54     JsonSlurper jsonSlurper = new JsonSlurper()
 
  55     ObjectMapper objectMapper = new ObjectMapper()
 
  56     TnNssmfUtils tnNssmfUtils = new TnNssmfUtils()
 
  57     private static final Logger logger = LoggerFactory.getLogger(TnAllocateNssi.class)
 
  59     void preProcessRequest(DelegateExecution execution) {
 
  60         logger.debug("Start preProcessRequest")
 
  61         execution.setVariable("prefix", Prefix)
 
  65             execution.setVariable("startTime", System.currentTimeMillis())
 
  67             msg = tnNssmfUtils.getExecutionInputParams(execution)
 
  68             logger.debug("Allocate TN NSSI input parameters: " + msg)
 
  70             tnNssmfUtils.setSdncCallbackUrl(execution, true)
 
  71             logger.debug("SDNC Callback URL: " + execution.getVariable("sdncCallbackUrl"))
 
  73             String additionalPropJsonStr = execution.getVariable("sliceParams")
 
  75             String tnNssiId = execution.getVariable("serviceInstanceID")
 
  76             if (isBlank(tnNssiId)) {
 
  77                 tnNssiId = UUID.randomUUID().toString()
 
  80             String operationId = UUID.randomUUID().toString()
 
  81             execution.setVariable("operationId", operationId)
 
  83             logger.debug("Generate new TN NSSI ID:" + tnNssiId)
 
  84             tnNssiId = UriUtils.encode(tnNssiId, "UTF-8")
 
  85             execution.setVariable("sliceServiceInstanceId", tnNssiId)
 
  87             String sliceServiceInstanceName = execution.getVariable("servicename")
 
  88             execution.setVariable("sliceServiceInstanceName", sliceServiceInstanceName)
 
  90             //additional properties
 
  91             String sliceProfile = jsonUtil.getJsonValue(additionalPropJsonStr, "sliceProfile")
 
  92             if (isBlank(sliceProfile)) {
 
  93                 msg = "Input sliceProfile is null"
 
  95                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
 
  97                 execution.setVariable("sliceProfile", sliceProfile)
 
 100             String transportSliceNetworks = jsonUtil.getJsonValue(additionalPropJsonStr, "transportSliceNetworks")
 
 101             if (isBlank(transportSliceNetworks)) {
 
 102                 msg = "Input transportSliceNetworks is null"
 
 104                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
 
 106                 execution.setVariable("transportSliceNetworks", transportSliceNetworks)
 
 108             logger.debug("transportSliceNetworks: " + transportSliceNetworks)
 
 110             String nsiInfoStr = jsonUtil.getJsonValue(additionalPropJsonStr, "nsiInfo")
 
 111             if (isBlank(nsiInfoStr)) {
 
 112                 msg = "Input nsiInfo is null"
 
 114                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
 
 116                 execution.setVariable("nsiInfo", nsiInfoStr)
 
 119             //nsiId is passed in from caller bpmn
 
 120             //String nsiIdStr = jsonUtil.getJsonValue(nsiInfo, "nsiId")
 
 121             //execution.setVariable("nsiId", nsiIdStr)
 
 123         } catch (BpmnError e) {
 
 125         } catch (Exception ex) {
 
 126             msg = "Exception in preProcessRequest " + ex.getMessage()
 
 128             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
 
 130         logger.debug("Finish preProcessRequest")
 
 134     void prepareDecomposeService(DelegateExecution execution) {
 
 135         logger.debug("Start prepareDecomposeService")
 
 137         String modelUuid = execution.getVariable("modelUuid")
 
 138         if (isBlank(modelUuid)) {
 
 139             msg = "Input modelUuid is null"
 
 141             exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
 
 144         String modelInvariantUuid = execution.getVariable("modelInvariantUuid")
 
 145         if (isBlank(modelInvariantUuid)) {
 
 146             msg = "Input modelInvariantUuid is null"
 
 148             exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
 
 151         String serviceModelInfo = """{
 
 152             "modelInvariantUuid":"${modelInvariantUuid}",
 
 153             "modelUuid":"${modelUuid}",
 
 156         execution.setVariable("ssServiceModelInfo", serviceModelInfo)
 
 158         logger.debug("Finish prepareDecomposeService")
 
 161     void processDecomposition(DelegateExecution execution) {
 
 162         logger.debug("Start processDecomposition")
 
 164         ServiceDecomposition tnNsstServiceDecomposition = execution.getVariable("tnNsstServiceDecomposition")
 
 165         logger.debug("tnNsstServiceDecomposition : " + tnNsstServiceDecomposition.toString())
 
 166         //TN NSST decomposition
 
 167         String tnModelVersion = tnNsstServiceDecomposition.getModelInfo().getModelVersion()
 
 168         String tnModelName = tnNsstServiceDecomposition.getModelInfo().getModelName()
 
 169         List<ServiceProxy> serviceProxyList = tnNsstServiceDecomposition.getServiceProxy()
 
 170         List<String> nsstInfoList = new ArrayList<>()
 
 171         for (ServiceProxy serviceProxy : serviceProxyList) {
 
 172             String nsstModelUuid = serviceProxy.getModelInfo().getModelUuid()
 
 173             String nsstModelInvariantUuid = serviceProxy.getModelInfo().getModelInvariantUuid()
 
 174             String name = serviceProxy.getModelInfo().getModelName()
 
 175             String nsstServiceModelInfo = """{
 
 176             "UUID":"${nsstModelUuid}",
 
 177             "invariantUUID":"${nsstModelInvariantUuid}",
 
 180             nsstInfoList.add(nsstServiceModelInfo)
 
 183         int maxIndex = nsstInfoList.size()
 
 185             String msg = "Exception in TN NSST processDecomposition. There is no NSST associated with TN NSST "
 
 187             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
 
 189         execution.setVariable("tnNsstInfoList", nsstInfoList)
 
 190         execution.setVariable("tnModelVersion", tnModelVersion)
 
 191         execution.setVariable("tnModelName", tnModelName)
 
 192         execution.setVariable("currentIndex", currentIndex)
 
 193         execution.setVariable("maxIndex", maxIndex)
 
 195         logger.debug("End processDecomposition")
 
 198     void prepareOofSelection(DelegateExecution execution) {
 
 199         logger.debug("Start prepareOofSelection")
 
 201         String urlString = UrnPropertiesReader.getVariable("mso.oof.endpoint", execution)
 
 202         logger.debug("get NSSI option OOF Url: " + urlString)
 
 203         //build oof request body
 
 204         String requestId = execution.getVariable("msoRequestId")
 
 205         String messageType = "NSISelectionResponse"
 
 206         Map<String, Object> profileInfo = objectMapper.readValue(execution.getVariable("sliceProfile"), Map.class)
 
 207         String modelUuid = execution.getVariable("modelUuid")
 
 208         String modelInvariantUuid = execution.getVariable("modelInvariantUuid")
 
 209         String modelName = execution.getVariable("tnModelName")
 
 210         String timeout = UrnPropertiesReader.getVariable("mso.adapters.oof.timeout", execution);
 
 211         List<String> nsstInfoList = objectMapper.readValue(execution.getVariable("nsstInfoList"), List.class)
 
 212         JsonArray capabilitiesList = new JsonArray()
 
 214         execution.setVariable("nssiSelection_Url", "/api/oof/selection/nsi/v1")
 
 215         execution.setVariable("nssiSelection_messageType", messageType)
 
 216         execution.setVariable("nssiSelection_correlator", requestId)
 
 217         execution.setVariable("nssiSelection_timeout", timeout)
 
 218         String oofRequest = buildSelectTnNssiRequest(requestId, messageType, modelUuid, modelInvariantUuid,
 
 219                 modelName, profileInfo, nsstInfoList, capabilitiesList, false)
 
 220         execution.setVariable("nssiSelection_oofRequest", oofRequest)
 
 222         logger.debug("Finish prepareOofSelection")
 
 225     String buildSelectTnNssiRequest(String requestId, String messageType, String UUID, String invariantUUID,
 
 226                                     String name, Map<String, Object> profileInfo,
 
 227                                     List<String> nsstInfoList, JsonArray capabilitiesList, Boolean preferReuse) {
 
 229         def transactionId = requestId
 
 230         logger.debug("transactionId is: " + transactionId)
 
 231         String correlator = requestId
 
 232         String callbackUrl = UrnPropertiesReader.getVariable("mso.adapters.oof.callback.endpoint") + "/" + messageType + "/" + correlator
 
 233         ObjectMapper objectMapper = new ObjectMapper()
 
 234         String profileJson = objectMapper.writeValueAsString(profileInfo)
 
 235         String nsstInfoListString = objectMapper.writeValueAsString(nsstInfoList)
 
 236         //Prepare requestInfo object
 
 237         JsonObject requestInfo = new JsonObject()
 
 238         requestInfo.addProperty("transactionId", transactionId)
 
 239         requestInfo.addProperty("requestId", requestId)
 
 240         requestInfo.addProperty("callbackUrl", callbackUrl)
 
 241         requestInfo.addProperty("sourceId", "SO")
 
 242         requestInfo.addProperty("timeout", 600)
 
 243         requestInfo.addProperty("numSolutions", 1)
 
 245         //Prepare serviceInfo object
 
 246         JsonObject ranNsstInfo = new JsonObject()
 
 247         ranNsstInfo.addProperty("UUID", UUID)
 
 248         ranNsstInfo.addProperty("invariantUUID", invariantUUID)
 
 249         ranNsstInfo.addProperty("name", name)
 
 251         JsonObject json = new JsonObject()
 
 252         json.add("requestInfo", requestInfo)
 
 253         json.add("NSTInfo", ranNsstInfo)
 
 254         json.addProperty("serviceProfile", profileJson)
 
 255         json.addProperty("NSSTInfo", nsstInfoListString)
 
 256         json.add("subnetCapabilities", capabilitiesList)
 
 257         json.addProperty("preferReuse", preferReuse)
 
 259         return json.toString()
 
 262     void processOofSelection(DelegateExecution execution) {
 
 263         logger.debug(Prefix + "processOofSelection method start")
 
 264         String oofResponse = execution.getVariable("nssiSelection_asyncCallbackResponse")
 
 265         String requestStatus = jsonUtil.getJsonValue(oofResponse, "requestStatus")
 
 266         if (requestStatus.equals("completed")) {
 
 267             List<String> solution = jsonUtil.StringArrayToList(jsonUtil.getJsonValue(oofResponse, "solutions"))
 
 268             boolean existingNSI = jsonUtil.getJsonValue(solution.get(0), "existingNSI")
 
 270                 def sharedNSISolution = jsonUtil.getJsonValue(solution.get(0), "sharedNSISolution")
 
 271                 execution.setVariable("sharedTnNssiSolution", sharedNSISolution)
 
 272                 logger.debug("sharedTnNssiSolution from OOF " + sharedNSISolution)
 
 273                 String tnServiceInstanceId = jsonUtil.getJsonValue(solution.get(0), "sharedNSISolution.NSIId")
 
 274                 execution.setVariable("tnServiceInstanceId", tnServiceInstanceId)
 
 275                 org.onap.so.bpmn.core.domain.ServiceInstance serviceInstance = new org.onap.so.bpmn.core.domain.ServiceInstance();
 
 276                 serviceInstance.setInstanceId(tnServiceInstanceId);
 
 277                 ServiceDecomposition serviceDecomposition = execution.getVariable("tnNsstServiceDecomposition")
 
 278                 serviceDecomposition.setServiceInstance(serviceInstance);
 
 279                 execution.setVariable("tnNsstServiceDecomposition", serviceDecomposition)
 
 280                 execution.setVariable("isOofTnNssiSelected", true)
 
 282                 def sliceProfiles = jsonUtil.getJsonValue(solution.get(0), "newNSISolution.sliceProfiles")
 
 283                 execution.setVariable("tnConstituentSliceProfiles", sliceProfiles)
 
 284                 execution.setVariable("isOofTnNssiSelected", false)
 
 285                 logger.debug("tnConstituentSliceProfiles list from OOF " + sliceProfiles)
 
 288             String statusMessage = jsonUtil.getJsonValue(oofResponse, "statusMessage")
 
 289             logger.error("received failed status from oof " + statusMessage)
 
 290             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, "Received a failed Async Response from OOF : " + statusMessage)
 
 293         logger.debug(Prefix + "processOofSelection method finished")
 
 296     void updateAAIOrchStatus(DelegateExecution execution) {
 
 297         logger.debug("Start updateAAIOrchStatus")
 
 298         String sliceServiceInstanceId = execution.getVariable("sliceServiceInstanceId")
 
 299         String orchStatus = execution.getVariable("orchestrationStatus")
 
 302             ServiceInstance si = new ServiceInstance()
 
 303             si.setOrchestrationStatus(orchStatus)
 
 304             AAIResourcesClient client = new AAIResourcesClient()
 
 305             AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE, sliceServiceInstanceId)
 
 306             client.update(uri, si)
 
 307         } catch (BpmnError e) {
 
 309         } catch (Exception ex) {
 
 310             String msg = "Exception in CreateSliceService.updateAAIOrchStatus " + ex.getMessage()
 
 312             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
 
 315         logger.debug("Finish updateAAIOrchStatus")
 
 319     void prepareUpdateJobStatus(DelegateExecution execution,
 
 322                                 String statusDescription) {
 
 323         String serviceId = execution.getVariable("sliceServiceInstanceId")
 
 324         String jobId = execution.getVariable("jobId")
 
 325         String nsiId = execution.getVariable("nsiId")
 
 327         ResourceOperationStatus roStatus = new ResourceOperationStatus()
 
 328         roStatus.setServiceId(serviceId)
 
 329         roStatus.setOperationId(jobId)
 
 330         roStatus.setResourceTemplateUUID(nsiId)
 
 331         roStatus.setOperType("Allocate")
 
 332         roStatus.setProgress(progress)
 
 333         roStatus.setStatus(status)
 
 334         roStatus.setStatusDescription(statusDescription)
 
 335         requestDBUtil.prepareUpdateResourceOperationStatus(execution, status)