From 902ec7ef30248c03096cf03da47e6bcca4372525 Mon Sep 17 00:00:00 2001 From: Arthur Martella Date: Thu, 21 Sep 2017 16:09:46 -0400 Subject: Move Homing Building Block into ONAP Files regarding the Homing building blocks added for use in vCPE flows. Change-Id: Iae9eb70b81ec7d473e6c4e9c821a9282dc40baa9 Issue-id: SO-138 Signed-off-by: Arthur Martella --- .../mso/bpmn/common/scripts/Homing.groovy | 259 ++++++++++++++++++++ .../common/scripts/ReceiveWorkflowMessage.groovy | 109 +++++++++ .../mso/bpmn/common/scripts/SNIROUtils.groovy | 262 +++++++++++++++++++++ 3 files changed, 630 insertions(+) create mode 100755 bpmn/MSOCommonBPMN/src/main/groovy/org/openecomp/mso/bpmn/common/scripts/Homing.groovy create mode 100644 bpmn/MSOCommonBPMN/src/main/groovy/org/openecomp/mso/bpmn/common/scripts/ReceiveWorkflowMessage.groovy create mode 100644 bpmn/MSOCommonBPMN/src/main/groovy/org/openecomp/mso/bpmn/common/scripts/SNIROUtils.groovy (limited to 'bpmn/MSOCommonBPMN/src/main/groovy/org') diff --git a/bpmn/MSOCommonBPMN/src/main/groovy/org/openecomp/mso/bpmn/common/scripts/Homing.groovy b/bpmn/MSOCommonBPMN/src/main/groovy/org/openecomp/mso/bpmn/common/scripts/Homing.groovy new file mode 100755 index 0000000000..dcbb73c7db --- /dev/null +++ b/bpmn/MSOCommonBPMN/src/main/groovy/org/openecomp/mso/bpmn/common/scripts/Homing.groovy @@ -0,0 +1,259 @@ +/* + * © 2014 AT&T Intellectual Property. All rights reserved. Used under license from AT&T Intellectual Property. + */ +package org.openecomp.mso.bpmn.common.scripts + +import org.camunda.bpm.engine.delegate.BpmnError +import org.camunda.bpm.engine.runtime.Execution + +import org.openecomp.mso.bpmn.common.scripts.AaiUtil +import org.openecomp.mso.bpmn.common.scripts.ExceptionUtil +import org.openecomp.mso.bpmn.common.scripts.SDNCAdapterUtils +import org.openecomp.mso.bpmn.core.domain.InventoryType +import org.openecomp.mso.bpmn.core.domain.Resource +import org.openecomp.mso.bpmn.core.domain.ServiceDecomposition +import org.openecomp.mso.bpmn.core.domain.Subscriber +import org.openecomp.mso.bpmn.core.json.JsonUtils +import org.openecomp.mso.rest.APIResponse +import org.openecomp.mso.rest.RESTClient +import org.openecomp.mso.rest.RESTConfig +import org.openecomp.mso.bpmn.common.scripts.AbstractServiceTaskProcessor + +import org.json.JSONArray +import org.json.JSONObject + +import static org.openecomp.mso.bpmn.common.scripts.GenericUtils.*; + +/** + * This class is contains the scripts used + * by the Homing Subflow building block. The + * subflow attempts to home the provided + * resources by calling sniro. + * + * @author cb645j + * + */ +class Homing extends AbstractServiceTaskProcessor{ + + ExceptionUtil exceptionUtil = new ExceptionUtil() + JsonUtils jsonUtil = new JsonUtils() + SNIROUtils sniroUtils = new SNIROUtils(this) + + /** + * This method validates the incoming variables. + * The method then prepares the sniro request + * and posts it to sniro's rest api. + * + * @param execution + * + * @author cb645j + */ + public void callSniro(Execution execution){ + def isDebugEnabled = execution.getVariable("isDebugLogEnabled") + execution.setVariable("prefix","HOME_") + utils.log("DEBUG", "*** Started Homing Call Sniro ***", isDebugEnabled) + try{ + execution.setVariable("rollbackData", null) + execution.setVariable("rolledBack", false) + + String requestId = execution.getVariable("msoRequestId") + utils.log("DEBUG", "Incoming Request Id is: " + requestId, isDebugEnabled) + String serviceInstanceId = execution.getVariable("serviceInstanceId") + utils.log("DEBUG", "Incoming Service Instance Id is: " + serviceInstanceId, isDebugEnabled) + ServiceDecomposition serviceDecomposition = execution.getVariable("serviceDecomposition") + utils.log("DEBUG", "Incoming Service Decomposition is: " + serviceDecomposition, isDebugEnabled) + String subscriberInfo = execution.getVariable("subscriberInfo") + utils.log("DEBUG", "Incoming Subscriber Information is: " + subscriberInfo, isDebugEnabled) + + if(isBlank(requestId) || isBlank(serviceInstanceId) || isBlank(serviceDecomposition.toString()) || isBlank(subscriberInfo)){ + exceptionUtil.buildAndThrowWorkflowException(execution, 4000, "A required input variable is missing or null") + }else{ + String subId = jsonUtil.getJsonValue(subscriberInfo, "globalSubscriberId") + String subName = jsonUtil.getJsonValue(subscriberInfo, "subscriberName") + String subCommonSiteId = "" + if(jsonUtil.jsonElementExist(subscriberInfo, "subscriberCommonSiteId")){ + subCommonSiteId = jsonUtil.getJsonValue(subscriberInfo, "subscriberCommonSiteId") + } + Subscriber subscriber = new Subscriber(subId, subName, subCommonSiteId) + + String cloudConfiguration = execution.getVariable("cloudConfiguration") // TODO Currently not being used + String homingParameters = execution.getVariable("homingParameters") // (aka. request parameters) Should be json format. TODO confirm its json format + + //Authentication + def authHeader = "" + String basicAuth = execution.getVariable("URN_mso_sniro_auth") + String msokey = execution.getVariable("URN_mso_msoKey") + String basicAuthValue = utils.encrypt(basicAuth, msokey) + if(basicAuthValue != null){ + utils.log("DEBUG", "Obtained BasicAuth username and password for SNIRO Adapter: " + basicAuthValue, isDebugEnabled) + try { + authHeader = utils.getBasicAuth(basicAuthValue, msokey) + execution.setVariable("BasicAuthHeaderValue",authHeader) + } catch (Exception ex) { + utils.log("DEBUG", "Unable to encode username and password string: " + ex, isDebugEnabled) + exceptionUtil.buildAndThrowWorkflowException(execution, 401, "Internal Error - Unable to encode username and password string") + } + }else{ + utils.log("DEBUG", "Unable to obtain BasicAuth - BasicAuth value null" , isDebugEnabled) + exceptionUtil.buildAndThrowWorkflowException(execution, 401, "Internal Error - BasicAuth value null") + } + + //Prepare Callback + String timeout = execution.getVariable("timeout") + if(isBlank(timeout)){ + timeout = execution.getVariable("URN_mso_sniro_timeout"); + if(isBlank(timeout)) { + timeout = "PT30M"; + } + } + utils.log("DEBUG", "Async Callback Timeout will be: " + timeout, isDebugEnabled) + + execution.setVariable("timeout", timeout); + execution.setVariable("correlator", requestId); + execution.setVariable("messageType", "SNIROResponse"); + + //Build Request & Call Sniro + String sniroRequest = sniroUtils.buildRequest(execution, requestId, serviceDecomposition, subscriber, homingParameters) + execution.setVariable("sniroRequest", sniroRequest) + utils.log("DEBUG", "SNIRO Request is: " + sniroRequest, isDebugEnabled) + + String endpoint = execution.getVariable("URN_mso_service_agnostic_sniro_endpoint") + String host = execution.getVariable("URN_mso_service_agnostic_sniro_host") + String url = host + endpoint + utils.log("DEBUG", "Posting to Sniro Url: " + url, isDebugEnabled) + + logDebug( "URL to be used is: " + url, isDebugEnabled) + + String basicAuthCred = utils.getBasicAuth(execution.getVariable("URN_aai_auth"),execution.getVariable("URN_mso_msoKey")) + + RESTConfig config = new RESTConfig(url); + RESTClient client = new RESTClient(config).addAuthorizationHeader(authHeader).addHeader("Content-Type", "application/json") + if (basicAuthCred != null && !"".equals(basicAuthCred)) { + client.addAuthorizationHeader(basicAuthCred) + } + APIResponse response = client.httpPost(sniroRequest) + + int responseCode = response.getStatusCode() + execution.setVariable("syncResponseCode", responseCode); + logDebug("SNIRO sync response code is: " + responseCode, isDebugEnabled) + String syncResponse = response.getResponseBodyAsString() + execution.setVariable("syncResponse", syncResponse); + logDebug("SNIRO sync response is: " + syncResponse, isDebugEnabled) + + utils.log("DEBUG", "*** Completed Homing Call Sniro ***", isDebugEnabled) + } + }catch(BpmnError b){ + throw b + }catch(Exception e){ + utils.log("DEBUG", "Error encountered within Homing CallSniro method: " + e, isDebugEnabled) + exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Internal Error - Occured in Homing CallSniro: " + e.getMessage()) + } + } + + /** + * This method processes the callback response + * and the contained homing solution. It sets + * homing solution assignment and license + * information to the corresponding resources + * + * @param execution + * + * @author cb645j + */ + public void processHomingSolution(Execution execution){ + def isDebugEnabled = execution.getVariable("isDebugLogEnabled") + utils.log("DEBUG", "*** Started Homing Process Homing Solution ***", isDebugEnabled) + try{ + String response = execution.getVariable("asyncCallbackResponse") + utils.log("DEBUG", "Sniro Async Callback Response is: " + response, isDebugEnabled) + utils.logAudit("Sniro Async Callback Response is: " + response) + + sniroUtils.validateCallbackResponse(execution, response) + String placements = jsonUtil.getJsonValue(response, "solutionInfo.placement") + + ServiceDecomposition decomposition = execution.getVariable("serviceDecomposition") + utils.log("DEBUG", "Service Decomposition: " + decomposition, isDebugEnabled) + + List resourceList = decomposition.getServiceResources() + JSONArray arr = new JSONArray(placements) + for(int i = 0; i < arr.length(); i++){ + JSONObject placement = arr.getJSONObject(i) + String jsonServiceResourceId = placement.getString("serviceResourceId") + for(Resource resource:resourceList){ + String serviceResourceId = resource.getResourceId() + if(serviceResourceId.equalsIgnoreCase(jsonServiceResourceId)){ + //match + String inventoryType = placement.getString("inventoryType") + resource.getHomingSolution().setInventoryType(InventoryType.valueOf(inventoryType)) + resource.getHomingSolution().setCloudRegionId(placement.getString("cloudRegionId")) + JSONArray assignmentArr = placement.getJSONArray("assignmentInfo") + Map assignmentMap = jsonUtil.entryArrayToMap(execution, assignmentArr.toString(), "variableName", "variableValue") + resource.getHomingSolution().setCloudOwner(assignmentMap.get("cloudOwner")) + resource.getHomingSolution().setAicClli(assignmentMap.get("aicClli")) + resource.getHomingSolution().setAicVersion(assignmentMap.get("aicVersion")) + if(inventoryType.equalsIgnoreCase("service")){ + resource.getHomingSolution().setVnfHostname(assignmentMap.get("vnfHostName")); + resource.getHomingSolution().setServiceInstanceId(placement.getString("serviceInstanceId")); + } + } + } + } + if(JsonUtils.jsonElementExist(response, "solutionInfo.licenseInfo")){ + String licenseInfo = jsonUtil.getJsonValue(response, "solutionInfo.licenseInfo") + JSONArray licenseArr = new JSONArray(licenseInfo) + for(int l = 0; l < licenseArr.length(); l++){ + JSONObject license = licenseArr.getJSONObject(l) + String jsonServiceResourceId = license.getString("serviceResourceId") + for(Resource resource:resourceList){ + String serviceResourceId = resource.getResourceId() + if(serviceResourceId.equalsIgnoreCase(jsonServiceResourceId)){ + //match + String jsonEntitlementPoolList = jsonUtil.getJsonValue(license.toString(), "entitlementPoolList") + List entitlementPoolList = jsonUtil.StringArrayToList(execution, jsonEntitlementPoolList) + resource.getHomingSolution().setEntitlementPoolList(entitlementPoolList) + + String jsonLicenseKeyGroupList = jsonUtil.getJsonValue(license.toString(), "licenseKeyGroupList") + List licenseKeyGroupList = jsonUtil.StringArrayToList(execution, jsonLicenseKeyGroupList) + resource.getHomingSolution().setLicenseKeyGroupList(licenseKeyGroupList) + } + } + } + } + execution.setVariable("serviceDecomposition", decomposition) + execution.setVariable("homingSolution", placements) //TODO - can be removed as output variable + + utils.log("DEBUG", "*** Completed Homing Process Homing Solution ***", isDebugEnabled) + }catch(BpmnError b){ + throw b + }catch(Exception e){ + utils.log("DEBUG", "Error encountered within Homing ProcessHomingSolution method: " + e, isDebugEnabled) + exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Internal Error - Occured in Homing ProcessHomingSolution") + } + } + + /** + * This method logs the start of DHVCreateService + * to make debugging easier. + * + * @param - execution + * @author cb645j + */ + public String logStart(Execution execution){ + def isDebugEnabled=execution.getVariable("isDebugLogEnabled") + String requestId = execution.getVariable("testReqId") + if(isBlank(requestId)){ + requestId = execution.getVariable("msoRequestId") + } + execution.setVariable("DHVCS_requestId", requestId) + utils.log("DEBUG", "***** STARTED Homing Subflow for request: " + requestId + " *****", "true") + utils.log("DEBUG", "****** Homing Subflow Global Debug Enabled: " + isDebugEnabled + " *****", "true") + utils.logAudit("***** STARTED Homing Subflow for request: " + requestId + " *****") + } + + + /** + * Auto-generated method stub + */ + public void preProcessRequest(Execution execution){} + +} diff --git a/bpmn/MSOCommonBPMN/src/main/groovy/org/openecomp/mso/bpmn/common/scripts/ReceiveWorkflowMessage.groovy b/bpmn/MSOCommonBPMN/src/main/groovy/org/openecomp/mso/bpmn/common/scripts/ReceiveWorkflowMessage.groovy new file mode 100644 index 0000000000..6ad03abec6 --- /dev/null +++ b/bpmn/MSOCommonBPMN/src/main/groovy/org/openecomp/mso/bpmn/common/scripts/ReceiveWorkflowMessage.groovy @@ -0,0 +1,109 @@ +package org.openecomp.mso.bpmn.common.scripts + +import groovy.json.* + +import org.apache.commons.lang3.* +import org.camunda.bpm.engine.delegate.BpmnError +import org.camunda.bpm.engine.runtime.Execution +import org.openecomp.mso.bpmn.common.scripts.AbstractServiceTaskProcessor +import org.openecomp.mso.bpmn.common.scripts.ExceptionUtil + + +class ReceiveWorkflowMessage extends AbstractServiceTaskProcessor { + + ExceptionUtil exceptionUtil = new ExceptionUtil() + + /** + * Process the incoming variables. + * + * @param execution The flow's execution instance. + */ +public void preProcessRequest (Execution execution) { + def method = getClass().getSimpleName() + '.preProcessRequest(' + + 'execution=' + execution.getId() + + ')' + def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled') + logDebug('Entered ' + method, isDebugLogEnabled) + + def prefix="RCVWFMSG_" + execution.setVariable("prefix", prefix) + setSuccessIndicator(execution, false) + + try { + + // Confirm that timeout value has been provided in 'RCVWFMSG_timeout'. + def timeout = execution.getVariable('RCVWFMSG_timeout') + logDebug('Timeout value is \'' + timeout + '\'', isDebugLogEnabled) + if ((timeout == null) || (timeout.isEmpty())) { + String msg = getProcessKey(execution) + ': Missing or empty input variable \'RCVWFMSG_timeout\'' + logDebug(msg, isDebugLogEnabled) + logError(msg) + exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg) + } + + // Confirm that message type has been provided in 'RCVWFMSG_messageType' + def messageType = execution.getVariable('RCVWFMSG_messageType') + logDebug('Message type is \'' + messageType + '\'', isDebugLogEnabled) + if ((messageType == null) || (messageType.isEmpty())) { + String msg = getProcessKey(execution) + ': Missing or empty input variable \'RCVWFMSG_messageType\'' + logDebug(msg, isDebugLogEnabled) + logError(msg) + exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg) + } + + // Confirm that correlator value has been provided in 'RCVWFMSG_correlator' + def correlator = execution.getVariable('RCVWFMSG_correlator') + logDebug('Correlator value is \'' + correlator + '\'', isDebugLogEnabled) + if ((correlator == null) || (correlator.isEmpty())) { + String msg = getProcessKey(execution) + ': Missing or empty input variable \'RCVWFMSG_correlator\'' + logDebug(msg, isDebugLogEnabled) + logError(msg) + exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg) + } + execution.setVariable(messageType + '_CORRELATOR', correlator) + + logDebug('Exited ' + method, isDebugLogEnabled) + } catch (BpmnError e) { + throw e + } catch (Exception e) { + String msg = 'Caught exception in ' + method + ": " + e + logDebug(msg, isDebugLogEnabled) + logError(msg) + exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg) + } + } + + /** + * Process a received message. + * + * @param execution The flow's execution instance. + */ + public void processReceivedMessage(Execution execution){ + def method = getClass().getSimpleName() + '.processReceivedMessage(' + + 'execution=' + execution.getId() + + ')' + def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled') + logDebug('Entered ' + method, isDebugLogEnabled) + + String messageType = null; + String receivedMessage = null; + + try { + messageType = execution.getVariable('RCVWFMSG_messageType') + receivedMessage = execution.getVariable(messageType + '_MESSAGE') + logDebug(getProcessKey(execution) + ": received message:\n" + receivedMessage, isDebugLogEnabled) + + // The received message is made available to the calling flow in WorkflowResponse + execution.setVariable("WorkflowResponse", receivedMessage) + + setSuccessIndicator(execution, true) + + logDebug('Exited ' + method, isDebugLogEnabled) + } catch (Exception e) { + receivedMessage = receivedMessage == null || String.valueOf(receivedMessage).isEmpty() ? "NONE" : receivedMessage + String msg = "Error processing received workflow message: " + receivedMessage + logDebug(getProcessKey(execution) + ': ' + msg, isDebugLogEnabled) + exceptionUtil.buildWorkflowException(execution, 7020, msg) + } + } +} diff --git a/bpmn/MSOCommonBPMN/src/main/groovy/org/openecomp/mso/bpmn/common/scripts/SNIROUtils.groovy b/bpmn/MSOCommonBPMN/src/main/groovy/org/openecomp/mso/bpmn/common/scripts/SNIROUtils.groovy new file mode 100644 index 0000000000..aba2b783e5 --- /dev/null +++ b/bpmn/MSOCommonBPMN/src/main/groovy/org/openecomp/mso/bpmn/common/scripts/SNIROUtils.groovy @@ -0,0 +1,262 @@ +package org.openecomp.mso.bpmn.common.scripts + +import org.camunda.bpm.engine.runtime.Execution +import org.openecomp.mso.bpmn.common.scripts.AbstractServiceTaskProcessor +import org.openecomp.mso.bpmn.common.scripts.ExceptionUtil +import org.openecomp.mso.bpmn.common.scripts.MsoUtils +import org.openecomp.mso.bpmn.core.domain.* +import org.openecomp.mso.bpmn.core.json.JsonUtils +import org.apache.commons.lang3.StringUtils + +import static org.openecomp.mso.bpmn.common.scripts.GenericUtils.* + +class SNIROUtils{ + + ExceptionUtil exceptionUtil = new ExceptionUtil() + JsonUtils jsonUtil = new JsonUtils() + + private AbstractServiceTaskProcessor utils + + public MsoUtils msoUtils = new MsoUtils() + + public SNIROUtils(AbstractServiceTaskProcessor taskProcessor) { + this.utils = taskProcessor + } + + /** + * This method builds the service-agnostic + * sniro json request to get a homing solution + * and license solution + * + * @param execution + * @param requestId + * @param decomposition - ServiceDecomposition object + * @param subscriber - Subscriber information + * @param homingParams - Homing/Request parameters + * + * @return request - sniro v2 payload + * + * @author cb645j + */ + public String buildRequest(Execution execution, String requestId, ServiceDecomposition decomposition, Subscriber subscriber, String homingParams){ + def isDebugEnabled = execution.getVariable("isDebugLogEnabled") + utils.log("DEBUG", "Started Building Sniro Request", isDebugEnabled) + def callbackUrl = utils.createWorkflowMessageAdapterCallbackURL(execution, "SNIROResponse", requestId) + def transactionId = requestId + //ServiceInstance Info + ServiceInstance serviceInstance = decomposition.getServiceInstance() + def serviceInstanceId + if(serviceInstance == null){ + utils.log("DEBUG", "Unable to obtain Service Instance Id, ServiceInstance Object is null" , isDebugEnabled) + exceptionUtil.buildAndThrowWorkflowException(execution, 400, "Internal Error - Unable to obtain Service Instance Id, ServiceInstance Object is null") + }else{ + serviceInstanceId = serviceInstance.getInstanceId() + } + //Model Info + ModelInfo model = decomposition.getModelInfo() + String modelType = model.getModelType() + String modelInvariantId = model.getModelInvariantUuid() + String modelVersionId = model.getModelUuid() + String modelName = model.getModelName() + String modelVersion = model.getModelVersion() + //Subscriber Info + String subscriberId = subscriber.getGlobalId() + String subscriberName = subscriber.getName() + String commonSiteId = subscriber.getCommonSiteId() + //OrderInfo + String orderInfo + if(!isBlank(homingParams)){ + orderInfo = homingParams.replaceAll("\"", "\\\\\"").replaceAll("\n", "").replaceAll("\r", "") + orderInfo = StringUtils.normalizeSpace(orderInfo) + } + + //Demands + String placementDemands = "" + StringBuilder sb = new StringBuilder() + List resourceList = decomposition.getServiceAllottedResources() + List vnfResourceList = decomposition.getServiceVnfs() + + // TODO: We should include both alloted resources and service resources in the placementDeamnds- not one or the other. + if(resourceList.isEmpty() || resourceList == null){ + utils.log("DEBUG", "Allotted Resources List is empty - will try to get service VNFs instead.", isDebugEnabled) + resourceList = decomposition.getServiceVnfs() + } + + if(resourceList.isEmpty() || resourceList == null){ + utils.log("DEBUG", "Resources List is Empty", isDebugEnabled) + }else{ + for(Resource resource:resourceList){ + ModelInfo resourceModelInfo = resource.getModelInfo() + ResourceInstance resourceInstance = resource.getResourceInstance() + def resourceInstanceType = resource.getResourceType() + def serviceResourceId = resource.getResourceId() //TODO - resourceId versus instanceId - should be what is put in AAI, whatever we put here will be what is in response, used to correlate + def resourceModuleName = resourceModelInfo.getModelInstanceName() + def resouceModelCustomizationId = resourceModelInfo.getModelCustomizationUuid() + def resouceModelInvariantId = resourceModelInfo.getModelInvariantUuid() + def resouceModelName = resourceModelInfo.getModelName() + def resouceModelVersion = resourceModelInfo.getModelVersion() + def resouceModelVersionId = resourceModelInfo.getModelUuid() + def resouceModelType = resourceModelInfo.getModelType() + def tenantId = "" //Optional + def tenantName = "" //Optional + + String demand = + """{ + "resourceInstanceType": "${resourceInstanceType}", + "serviceResourceId": "${serviceResourceId}", + "resourceModuleName": "${resourceModuleName}", + "resourceModelInfo": { + "modelCustomizationId": "${resouceModelCustomizationId}", + "modelInvariantId": "${resouceModelInvariantId}", + "modelName": "${resouceModelName}", + "modelVersion": "${resouceModelVersion}", + "modelVersionId": "${resouceModelVersionId}", + "modelType": "${resouceModelType}" + }, + "tenantId": "${tenantId}", + "tenantName": "${tenantName}" + },""" + + placementDemands = sb.append(demand) + } + placementDemands = placementDemands.substring(0, placementDemands.length() - 1); + } + + String licenseDemands = "" + sb = new StringBuilder() + if(vnfResourceList.isEmpty() || vnfResourceList == null){ + utils.log("DEBUG", "Vnf Resources List is Empty", isDebugEnabled) + }else{ + for(VnfResource vnfResource:vnfResourceList){ + ModelInfo vnfResourceModelInfo = vnfResource.getModelInfo() + ResourceInstance vnfResourceInstance = vnfResource.getResourceInstance() + def resourceInstanceType = vnfResource.getResourceType() + def serviceResourceId = vnfResource.getResourceId() + def resourceModuleName = vnfResourceModelInfo.getModelInstanceName() + def resouceModelCustomizationId = vnfResourceModelInfo.getModelCustomizationUuid() + def resouceModelInvariantId = vnfResourceModelInfo.getModelInvariantUuid() + def resouceModelName = vnfResourceModelInfo.getModelName() + def resouceModelVersion = vnfResourceModelInfo.getModelVersion() + def resouceModelVersionId = vnfResourceModelInfo.getModelUuid() + def resouceModelType = vnfResourceModelInfo.getModelType() + + String demand = + """{ + "resourceInstanceType": "${resourceInstanceType}", + "serviceResourceId": "${serviceResourceId}", + "resourceModuleName": "${resourceModuleName}", + "resourceModelInfo": { + "modelCustomizationId": "${resouceModelCustomizationId}", + "modelInvariantId": "${resouceModelInvariantId}", + "modelName": "${resouceModelName}", + "modelVersion": "${resouceModelVersion}", + "modelVersionId": "${resouceModelVersionId}", + "modelType": "${resouceModelType}" + } + },""" + + licenseDemands = sb.append(demand) + } + licenseDemands = licenseDemands.substring(0, licenseDemands.length() - 1); + } + + String request = + """{ + "requestInfo": { + "transactionId": "${transactionId}", + "requestId": "${requestId}", + "callbackUrl": "${callbackUrl}", + "sourceId": "mso", + "optimizer": [ + "placement", + "license" + ], + "numSolutions": 1, + "timeout": 600 + }, + "placementInfo": { + "serviceModelInfo": { + "modelType": "${modelType}", + "modelInvariantId": "${modelInvariantId}", + "modelVersionId": "${modelVersionId}", + "modelName": "${modelName}", + "modelVersion": "${modelVersion}" + }, + "subscriberInfo": { + "globalSubscriberId": "${subscriberId}", + "subscriberName": "${subscriberName}", + "subscriberCommonSiteId": "${commonSiteId}" + }, + "demandInfo": { + "placementDemand": [ + ${placementDemands} + ], + "licenseDemand": [ + ${licenseDemands} + ] + }, + "policyId": [], + "serviceInstanceId": "${serviceInstanceId}", + "orderInfo": "{\\\"requestParameters\\\": ${orderInfo}}" + } + }""" + + utils.log("DEBUG", "Completed Building Sniro Request", isDebugEnabled) + return request + } + + /** + * This method validates the callback response + * from Sniro. If the response contains an + * exception the method will build and throw + * a workflow exception. + * + * @param execution + * @param response - the async callback response from sniro + * + * @author cb645j + */ + public void validateCallbackResponse(Execution execution, String response){ + def isDebugEnabled = execution.getVariable("isDebugLogEnabled") + String placements = "" + if(isBlank(response)){ + exceptionUtil.buildAndThrowWorkflowException(execution, 5000, "Sniro Async Callback Response is Empty") + }else{ + if(JsonUtils.jsonElementExist(response, "solutionInfo.placement")){ + placements = jsonUtil.getJsonValue(response, "solutionInfo.placement") + if(isBlank(placements) || placements.equalsIgnoreCase("[]")){ + String statusMessage = jsonUtil.getJsonValue(response, "statusMessage") + if(isBlank(statusMessage)){ + utils.log("DEBUG", "Error Occured in Homing: Sniro Async Callback Response does not contain placement solution.", isDebugEnabled) + exceptionUtil.buildAndThrowWorkflowException(execution, 400, "Sniro Async Callback Response does not contain placement solution.") + }else{ + utils.log("DEBUG", "Error Occured in Homing: " + statusMessage, isDebugEnabled) + exceptionUtil.buildAndThrowWorkflowException(execution, 400, statusMessage) + } + }else{ + return + } + }else if(JsonUtils.jsonElementExist(response, "requestError") == true){ + String errorMessage = "" + if(response.contains("policyException")){ + String text = jsonUtil.getJsonValue(response, "requestError.policyException.text") + errorMessage = "Sniro Async Callback Response contains a Request Error Policy Exception: " + text + }else if(response.contains("serviceException")){ + String text = jsonUtil.getJsonValue(response, "requestError.serviceException.text") + errorMessage = "Sniro Async Callback Response contains a Request Error Service Exception: " + text + }else{ + errorMessage = "Sniro Async Callback Response contains a Request Error. Unable to determine the Request Error Exception." + } + utils.log("DEBUG", "Error Occured in Homing: " + errorMessage, isDebugEnabled) + exceptionUtil.buildAndThrowWorkflowException(execution, 400, errorMessage) + + }else{ + utils.log("DEBUG", "Error Occured in Homing: Received an Unknown Async Callback Response from Sniro.", isDebugEnabled) + exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Received an Unknown Async Callback Response from Sniro.") + } + } + + } + + +} \ No newline at end of file -- cgit 1.2.3-korg