aboutsummaryrefslogtreecommitdiffstats
path: root/bpmn/MSOCommonBPMN/src/main/groovy/org/openecomp/mso
diff options
context:
space:
mode:
authorMarcus G K Williams <marcus.williams@intel.com>2018-03-14 15:07:31 -0700
committerMarcus Williams <marcus.williams@intel.com>2018-03-27 21:34:27 +0000
commitc4c512c8b0a46d92f7862b9f01a7969975937e06 (patch)
tree307ea34a7aab41f51a6e4434553c972555f41ff7 /bpmn/MSOCommonBPMN/src/main/groovy/org/openecomp/mso
parentb4473da1a753e63e66f5a9a3b1984fd4736273c2 (diff)
Refactor homing flows for OOF/HPA
1. Split Homing into OOF and SNIRO versions 2. Added OOF API interactions 3. Added Unit tests for OOF Homing Code Issue-ID: SO-404 Change-Id: Ifeeeec9ea450d8b330110a565208ed89a1e18cde Signed-off-by: Marcus G K Williams <marcus.williams@intel.com>
Diffstat (limited to 'bpmn/MSOCommonBPMN/src/main/groovy/org/openecomp/mso')
-rwxr-xr-xbpmn/MSOCommonBPMN/src/main/groovy/org/openecomp/mso/bpmn/common/scripts/Homing.groovy274
-rw-r--r--bpmn/MSOCommonBPMN/src/main/groovy/org/openecomp/mso/bpmn/common/scripts/OofHoming.groovy289
-rw-r--r--bpmn/MSOCommonBPMN/src/main/groovy/org/openecomp/mso/bpmn/common/scripts/OofUtils.groovy405
-rw-r--r--bpmn/MSOCommonBPMN/src/main/groovy/org/openecomp/mso/bpmn/common/scripts/SNIROUtils.groovy2
-rwxr-xr-xbpmn/MSOCommonBPMN/src/main/groovy/org/openecomp/mso/bpmn/common/scripts/SniroHoming.groovy274
5 files changed, 969 insertions, 275 deletions
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
deleted file mode 100755
index 2325e6c3d3..0000000000
--- a/bpmn/MSOCommonBPMN/src/main/groovy/org/openecomp/mso/bpmn/common/scripts/Homing.groovy
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * ONAP - SO
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-package org.openecomp.mso.bpmn.common.scripts
-
-import org.camunda.bpm.engine.delegate.BpmnError
-import org.camunda.bpm.engine.delegate.DelegateExecution
-
-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.domain.VnfResource
-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(DelegateExecution 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)
-
- RESTConfig config = new RESTConfig(url);
- RESTClient client = new RESTClient(config).addAuthorizationHeader(authHeader).addHeader("Content-Type", "application/json")
- 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(DelegateExecution 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.placementInfo")
-
- ServiceDecomposition decomposition = execution.getVariable("serviceDecomposition")
- utils.log("DEBUG", "Service Decomposition: " + decomposition, isDebugEnabled)
-
- List<Resource> 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"))
- resource.getHomingSolution().setRehome(placement.getBoolean("isRehome"))
- JSONArray assignmentArr = placement.getJSONArray("assignmentInfo")
- Map<String, String> 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")){
- VnfResource vnf = new VnfResource()
- vnf.setVnfHostname(assignmentMap.get("vnfHostName"))
- resource.getHomingSolution().setVnf(vnf)
- 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<String> entitlementPoolList = jsonUtil.StringArrayToList(execution, jsonEntitlementPoolList)
- resource.getHomingSolution().getLicense().setEntitlementPoolList(entitlementPoolList)
-
- String jsonLicenseKeyGroupList = jsonUtil.getJsonValue(license.toString(), "licenseKeyGroupList")
- List<String> licenseKeyGroupList = jsonUtil.StringArrayToList(execution, jsonLicenseKeyGroupList)
- resource.getHomingSolution().getLicense().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(DelegateExecution 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(DelegateExecution execution){}
-
-}
diff --git a/bpmn/MSOCommonBPMN/src/main/groovy/org/openecomp/mso/bpmn/common/scripts/OofHoming.groovy b/bpmn/MSOCommonBPMN/src/main/groovy/org/openecomp/mso/bpmn/common/scripts/OofHoming.groovy
new file mode 100644
index 0000000000..5e7ed982a6
--- /dev/null
+++ b/bpmn/MSOCommonBPMN/src/main/groovy/org/openecomp/mso/bpmn/common/scripts/OofHoming.groovy
@@ -0,0 +1,289 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.openecomp.mso.bpmn.common.scripts
+
+import org.camunda.bpm.engine.delegate.BpmnError
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+
+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.domain.VnfResource
+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 contains the scripts used
+ * by the OOF Homing Subflow building block. The
+ * subflow attempts to home the provided
+ * resources by calling OOF.
+ */
+class OofHoming extends AbstractServiceTaskProcessor {
+
+ ExceptionUtil exceptionUtil = new ExceptionUtil()
+ JsonUtils jsonUtil = new JsonUtils()
+ OofUtils oofUtils = new OofUtils(this)
+
+ /**
+ * This method validates the incoming variables.
+ * The method then prepares the OOF request
+ * and posts it to OOF's rest api.
+ *
+ * @param execution
+ */
+ public void callOof(DelegateExecution execution) {
+ def isDebugEnabled = execution.getVariable("isDebugLogEnabled")
+ execution.setVariable("prefix", "HOME_")
+ utils.log("DEBUG", "*** Started Homing Call OOF ***", 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)
+ Map customerLocation = execution.getVariable("customerLocation")
+ utils.log("DEBUG", "Incoming Customer Location is: " + customerLocation.toString(), isDebugEnabled)
+ String cloudOwner = execution.getVariable("cloudOwner")
+ utils.log("DEBUG", "Incoming cloudOwner is: " + cloudOwner, isDebugEnabled)
+ String cloudRegionId = execution.getVariable("cloudRegionId")
+ utils.log("DEBUG", "Incoming cloudRegionId is: " + cloudRegionId, isDebugEnabled)
+
+ if (isBlank(requestId) ||
+ isBlank(serviceInstanceId) ||
+ isBlank(serviceDecomposition.toString()) ||
+ isBlank(subscriberInfo) ||
+ isBlank(customerLocation.toString()) ||
+ isBlank(cloudOwner) ||
+ isBlank(cloudRegionId)) {
+ 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)
+
+ //Authentication
+ def authHeader = ""
+ String basicAuth = execution.getVariable("URN_mso_oof_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 OOF 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_oof_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", "oofResponse")
+
+ //Build Request & Call OOF
+ String oofRequest = oofUtils.buildRequest(execution, requestId, serviceDecomposition,
+ subscriber, customerLocation)
+ execution.setVariable("oofRequest", oofRequest)
+ utils.log("DEBUG", "OOF Request is: " + oofRequest, isDebugEnabled)
+
+ String endpoint = execution.getVariable("URN_mso_service_agnostic_oof_endpoint")
+ String host = execution.getVariable("URN_mso_service_agnostic_oof_host")
+ String url = host + endpoint
+ utils.log("DEBUG", "Posting to OOF Url: " + url, isDebugEnabled)
+
+ logDebug("URL to be used is: " + url, isDebugEnabled)
+
+ RESTConfig config = new RESTConfig(url)
+ RESTClient client = new RESTClient(config).addAuthorizationHeader(authHeader).
+ addHeader("Content-Type", "application/json")
+ APIResponse response = client.httpPost(oofRequest)
+
+ int responseCode = response.getStatusCode()
+ execution.setVariable("syncResponseCode", responseCode)
+ logDebug("OOF sync response code is: " + responseCode, isDebugEnabled)
+ String syncResponse = response.getResponseBodyAsString()
+ execution.setVariable("syncResponse", syncResponse)
+ logDebug("OOF sync response is: " + syncResponse, isDebugEnabled)
+
+ utils.log("DEBUG", "*** Completed Homing Call OOF ***", isDebugEnabled)
+ }
+ } catch (BpmnError b) {
+ throw b
+ } catch (Exception e) {
+ utils.log("DEBUG", "Error encountered within Homing callOof method: " + e, isDebugEnabled)
+ exceptionUtil.buildAndThrowWorkflowException(execution, 2500,
+ "Internal Error - Occured in Homing callOof: " + 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
+ */
+ public void processHomingSolution(DelegateExecution execution) {
+ def isDebugEnabled = execution.getVariable("isDebugLogEnabled")
+ utils.log("DEBUG", "*** Started Homing Process Homing Solution ***", isDebugEnabled)
+ try {
+ String response = execution.getVariable("asyncCallbackResponse")
+ utils.log("DEBUG", "OOF Async Callback Response is: " + response, isDebugEnabled)
+ utils.logAudit("OOF Async Callback Response is: " + response)
+
+ oofUtils.validateCallbackResponse(execution, response)
+ String placements = jsonUtil.getJsonValue(response, "solutions.placementSolutions")
+ utils.log("DEBUG", "****** Solution Placements: " + placements + " *****", isDebugEnabled)
+
+ ServiceDecomposition decomposition = execution.getVariable("serviceDecomposition")
+ utils.log("DEBUG", "Service Decomposition: " + decomposition, isDebugEnabled)
+
+ List<Resource> resourceList = decomposition.getServiceResources()
+ JSONArray arr = new JSONArray(placements)
+ for (int i = 0; i < arr.length(); i++) {
+ JSONObject placement = arr.getJSONObject(i)
+ utils.log("DEBUG", "****** JSONObject is: " + placement + " *****", "true")
+ String jsonServiceResourceId = placement.getString("serviceResourceId")
+ for (Resource resource : resourceList) {
+ String serviceResourceId = resource.getResourceId()
+ if (serviceResourceId.equalsIgnoreCase(jsonServiceResourceId)) {
+ JSONObject solution = placement.getJSONObject("solution")
+ String solutionType = solution.getString("identifierType")
+ String inventoryType = ""
+ if (solutionType.equalsIgnoreCase("serviceInstanceId")) {
+ inventoryType = "service"
+ } else {
+ inventoryType = "cloud"
+
+ }
+ resource.getHomingSolution().setInventoryType(InventoryType.valueOf(inventoryType))
+
+ // TODO Deal with Placement Solutions & Assignment Info here
+ JSONArray assignmentArr = placement.getJSONArray("assignmentInfo")
+ Map<String, String> assignmentMap = jsonUtil.entryArrayToMap(execution, assignmentArr.toString(), "key", "value")
+ resource.getHomingSolution().setCloudOwner(assignmentMap.get("cloudOwner"))
+ resource.getHomingSolution().setCloudRegionId(assignmentMap.get("cloudRegionId"))
+ if (inventoryType.equalsIgnoreCase("service")) {
+ resource.getHomingSolution().setRehome(assignmentMap.get("isRehome").toBoolean())
+ VnfResource vnf = new VnfResource()
+ vnf.setVnfHostname(assignmentMap.get("vnfHostName"))
+ resource.getHomingSolution().setVnf(vnf)
+ resource.getHomingSolution().setServiceInstanceId(solution.getJSONArray("identifiers")[0].toString())
+ }
+ }
+ }
+ }
+ if (JsonUtils.jsonElementExist(response, "solutions.licenseSolutions")) {
+ String licenseSolutions = jsonUtil.getJsonValue(response, "solutions.licenseSolutions")
+ JSONArray licenseArr = new JSONArray(licenseSolutions)
+ 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)) {
+ String jsonEntitlementPoolList = jsonUtil.getJsonValue(license.toString(), "entitlementPoolUUID")
+ List<String> entitlementPoolList = jsonUtil.StringArrayToList(execution, jsonEntitlementPoolList)
+ resource.getHomingSolution().getLicense().setEntitlementPoolList(entitlementPoolList)
+
+ String jsonLicenseKeyGroupList = jsonUtil.getJsonValue(license.toString(), "licenseKeyGroupUUID")
+ List<String> licenseKeyGroupList = jsonUtil.StringArrayToList(execution, jsonLicenseKeyGroupList)
+ resource.getHomingSolution().getLicense().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 - Occurred in Homing ProcessHomingSolution")
+ }
+ }
+
+ /**
+ * This method logs the start of DHVCreateService
+ * to make debugging easier.
+ *
+ * @param - execution
+ */
+ public String logStart(DelegateExecution 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(DelegateExecution execution) {}
+ // Not Implemented Method
+}
diff --git a/bpmn/MSOCommonBPMN/src/main/groovy/org/openecomp/mso/bpmn/common/scripts/OofUtils.groovy b/bpmn/MSOCommonBPMN/src/main/groovy/org/openecomp/mso/bpmn/common/scripts/OofUtils.groovy
new file mode 100644
index 0000000000..fc7c62baa7
--- /dev/null
+++ b/bpmn/MSOCommonBPMN/src/main/groovy/org/openecomp/mso/bpmn/common/scripts/OofUtils.groovy
@@ -0,0 +1,405 @@
+package org.openecomp.mso.bpmn.common.scripts
+
+import org.apache.commons.lang3.StringUtils
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+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.HomingSolution
+import org.openecomp.mso.bpmn.core.domain.ModelInfo
+import org.openecomp.mso.bpmn.core.domain.Resource
+import org.openecomp.mso.bpmn.core.domain.ServiceDecomposition
+import org.openecomp.mso.bpmn.core.domain.ServiceInstance
+import org.openecomp.mso.bpmn.core.domain.Subscriber
+import org.openecomp.mso.bpmn.core.domain.VnfResource
+import org.openecomp.mso.bpmn.core.json.JsonUtils
+
+import static org.openecomp.mso.bpmn.common.scripts.GenericUtils.*
+
+class OofUtils {
+
+ ExceptionUtil exceptionUtil = new ExceptionUtil()
+ JsonUtils jsonUtil = new JsonUtils()
+
+ private AbstractServiceTaskProcessor utils
+
+ public MsoUtils msoUtils = new MsoUtils()
+
+ public OofUtils(AbstractServiceTaskProcessor taskProcessor) {
+ this.utils = taskProcessor
+ }
+
+ /**
+ * This method builds the service-agnostic
+ * OOF json request to get a homing solution
+ * and license solution
+ *
+ * @param execution
+ * @param requestId
+ * @param decomposition - ServiceDecomposition object
+ * @param customerLocation -
+ * @param existingCandidates -
+ * @param excludedCandidates -
+ * @param requiredCandidates -
+ *
+ * @return request - OOF v1 payload - https://wiki.onap.org/pages/viewpage.action?pageId=25435066
+ */
+ String buildRequest(DelegateExecution execution,
+ String requestId,
+ ServiceDecomposition decomposition,
+ Subscriber subscriber,
+ Map customerLocation,
+ ArrayList existingCandidates = null,
+ ArrayList excludedCandidates = null,
+ ArrayList requiredCandidates = null) {
+ def isDebugEnabled = execution.getVariable("isDebugLogEnabled")
+ utils.log("DEBUG", "Started Building OOF Request", isDebugEnabled)
+ def callbackUrl = utils.createWorkflowMessageAdapterCallbackURL(execution, "oofResponse", requestId)
+ def transactionId = requestId
+ //ServiceInstance Info
+ ServiceInstance serviceInstance = decomposition.getServiceInstance()
+ def serviceInstanceId = ""
+ def serviceInstanceName = ""
+ 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()
+ serviceInstanceName = serviceInstance.getInstanceName()
+ }
+ //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()
+
+ //Determine RequestType
+ //TODO Figure out better way to determine this
+ String requestType = "create"
+ List<Resource> resources = decomposition.getServiceResources()
+ for(Resource r:resources){
+ HomingSolution currentSolution = (HomingSolution) r.getCurrentHomingSolution()
+ if(currentSolution != null){
+ requestType = "speed changed"
+ }
+ }
+
+ //Demands
+ String placementDemands = ""
+ StringBuilder sb = new StringBuilder()
+ List<Resource> resourceList = decomposition.getServiceAllottedResources()
+ List<VnfResource> vnfResourceList = decomposition.getServiceVnfs()
+
+ 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()
+ def serviceResourceId = resource.getResourceId()
+ def resourceModuleName = resource.getResourceType()
+ def resouceModelInvariantId = resourceModelInfo.getModelInvariantUuid()
+ def resouceModelName = resourceModelInfo.getModelName()
+ def resouceModelVersion = resourceModelInfo.getModelVersion()
+ def resouceModelVersionId = resourceModelInfo.getModelUuid()
+ def resouceModelType = resourceModelInfo.getModelType()
+ def tenantId = execution.getTenantId()
+ def requiredCandidatesJson = ""
+
+ requiredCandidatesJson = createCandidateJson(
+ existingCandidates,
+ excludedCandidates,
+ requiredCandidates)
+
+ String demand =
+ "{\n" +
+ "\"resourceModuleName\": \"${resourceModuleName}\",\n" +
+ "\"serviceResourceId\": \"${serviceResourceId}\",\n" +
+ "\"tenantId\": \"${tenantId}\",\n" +
+ "\"resourceModelInfo\": {\n" +
+ " \"modelInvariantId\": \"${resouceModelInvariantId}\",\n" +
+ " \"modelVersionId\": \"${resouceModelVersionId}\",\n" +
+ " \"modelName\": \"${resouceModelName}\",\n" +
+ " \"modelType\": \"${resouceModelType}\",\n" +
+ " \"modelVersion\": \"${resouceModelVersion}\",\n" +
+ " \"modelCustomizationName\": \"\"\n" +
+ " }" + requiredCandidatesJson + "\n" +
+ "},"
+
+ 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()
+ def resourceInstanceType = vnfResource.getResourceType()
+ def serviceResourceId = vnfResource.getResourceId()
+ def resourceModuleName = vnfResource.getResourceType()
+ def resouceModelInvariantId = vnfResourceModelInfo.getModelInvariantUuid()
+ def resouceModelName = vnfResourceModelInfo.getModelName()
+ def resouceModelVersion = vnfResourceModelInfo.getModelVersion()
+ def resouceModelVersionId = vnfResourceModelInfo.getModelUuid()
+ def resouceModelType = vnfResourceModelInfo.getModelType()
+
+ // TODO Add Existing Licenses to demand
+ //"existingLicenses": {
+ //"entitlementPoolUUID": ["87257b49-9602-4ca1-9817-094e52bc873b",
+ // "43257b49-9602-4fe5-9337-094e52bc9435"],
+ //"licenseKeyGroupUUID": ["87257b49-9602-4ca1-9817-094e52bc873b",
+ // "43257b49-9602-4fe5-9337-094e52bc9435"]
+ //}
+
+ String licenseDemand =
+ "{\n" +
+ "\"resourceModuleName\": \"${resourceModuleName}\",\n" +
+ "\"serviceResourceId\": \"${serviceResourceId}\",\n" +
+ "\"resourceInstanceType\": \"${resourceInstanceType}\",\n" +
+ "\"resourceModelInfo\": {\n" +
+ " \"modelInvariantId\": \"${resouceModelInvariantId}\",\n" +
+ " \"modelVersionId\": \"${resouceModelVersionId}\",\n" +
+ " \"modelName\": \"${resouceModelName}\",\n" +
+ " \"modelType\": \"${resouceModelType}\",\n" +
+ " \"modelVersion\": \"${resouceModelVersion}\",\n" +
+ " \"modelCustomizationName\": \"\"\n" +
+ " }\n"
+ "},"
+
+ licenseDemands = sb.append(licenseDemand)
+ }
+ licenseDemands = licenseDemands.substring(0, licenseDemands.length() - 1)
+ }
+
+ String request =
+ "{\n" +
+ " \"requestInfo\": {\n" +
+ " \"transactionId\": \"${transactionId}\",\n" +
+ " \"requestId\": \"${requestId}\",\n" +
+ " \"callbackUrl\": \"${callbackUrl}\",\n" +
+ " \"sourceId\": \"so\",\n" +
+ " \"requestType\": \"${requestType}\"," +
+ " \"numSolutions\": 1,\n" +
+ " \"optimizers\": [\"placement\"],\n" +
+ " \"timeout\": 600\n" +
+ " },\n" +
+ " \"placementInfo\": {\n" +
+ " \"requestParameters\": {\n" +
+ " \"customerLatitude\": \"${customerLocation.customerLatitude}\",\n" +
+ " \"customerLongitude\": \"${customerLocation.customerLongitude}\",\n" +
+ " \"customerName\": \"${customerLocation.customerName}\"\n" +
+ " }," +
+ " \"subscriberInfo\": { \n" +
+ " \"globalSubscriberId\": \"${subscriberId}\",\n" +
+ " \"subscriberName\": \"${subscriberName}\",\n" +
+ " \"subscriberCommonSiteId\": \"${commonSiteId}\"\n" +
+ " },\n" +
+ " \"placementDemands\": [\n" +
+ " ${placementDemands}\n" +
+ " ]\n" +
+ " },\n" +
+ " \"serviceInfo\": {\n" +
+ " \"serviceInstanceId\": \"${serviceInstanceId}\",\n" +
+ " \"serviceName\": \"${serviceInstanceName}\",\n" +
+ " \"modelInfo\": {\n" +
+ " \"modelType\": \"${modelType}\",\n" +
+ " \"modelInvariantId\": \"${modelInvariantId}\",\n" +
+ " \"modelVersionId\": \"${modelVersionId}\",\n" +
+ " \"modelName\": \"${modelName}\",\n" +
+ " \"modelVersion\": \"${modelVersion}\",\n" +
+ " \"modelCustomizationName\": \"\"\n" +
+ " }\n" +
+ " },\n" +
+ " \"licenseInfo\": {\n" +
+ " \"licenseDemands\": [\n" +
+ " ${licenseDemands}\n" +
+ " }]\n" +
+ " }\n" +
+ "}"
+
+
+ utils.log("DEBUG", "Completed Building OOF Request", isDebugEnabled)
+ return request
+ }
+
+ /**
+ * This method validates the callback response
+ * from OOF. If the response contains an
+ * exception the method will build and throw
+ * a workflow exception.
+ *
+ * @param execution
+ * @param response - the async callback response from oof
+ */
+ Void validateCallbackResponse(DelegateExecution execution, String response) {
+ def isDebugEnabled = execution.getVariable("isDebugLogEnabled")
+ String placements = ""
+ if (isBlank(response)) {
+ exceptionUtil.buildAndThrowWorkflowException(execution, 5000, "OOF Async Callback Response is Empty")
+ } else {
+ if (JsonUtils.jsonElementExist(response, "solutions.placementSolutions")) {
+ placements = jsonUtil.getJsonValue(response, "solutions.placementSolutions")
+ if (isBlank(placements) || placements.equalsIgnoreCase("[]")) {
+ String statusMessage = jsonUtil.getJsonValue(response, "statusMessage")
+ if (isBlank(statusMessage)) {
+ utils.log("DEBUG", "Error Occurred in Homing: OOF Async Callback Response does " +
+ "not contain placement solution.", isDebugEnabled)
+ exceptionUtil.buildAndThrowWorkflowException(execution, 400,
+ "OOF Async Callback Response does not contain placement solution.")
+ } else {
+ utils.log("DEBUG", "Error Occurred 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 = "OOF Async Callback Response contains a Request Error Policy Exception: " + text
+ } else if (response.contains("serviceException")) {
+ String text = jsonUtil.getJsonValue(response, "requestError.serviceException.text")
+ errorMessage = "OOF Async Callback Response contains a Request Error Service Exception: " + text
+ } else {
+ errorMessage = "OOF Async Callback Response contains a Request Error. Unable to determine the Request Error Exception."
+ }
+ utils.log("DEBUG", "Error Occurred in Homing: " + errorMessage, isDebugEnabled)
+ exceptionUtil.buildAndThrowWorkflowException(execution, 400, errorMessage)
+
+ } else {
+ utils.log("DEBUG", "Error Occurred in Homing: Received an Unknown Async Callback Response from OOF.", isDebugEnabled)
+ exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Received an Unknown Async Callback Response from OOF.")
+ }
+ }
+
+ }
+
+ /**
+ * This method creates candidates json for placement Demands.
+ *
+ * @param execution
+ * @param existingCandidates -
+ * @param excludedCandidates -
+ * @param requiredCandidates -
+ *
+ * @return candidatesJson - a JSON string with candidates
+ */
+ String createCandidateJson(ArrayList existingCandidates = null,
+ ArrayList excludedCandidates = null,
+ ArrayList requiredCandidates = null) {
+ def candidatesJson = ""
+ def type = ""
+ if (existingCandidates != null && existingCandidates != {}) {
+ sb = new StringBuilder()
+ sb.append(",\n" +
+ " \"existingCandidates\": [\n")
+ def existingCandidateJson = ""
+ existingCandidates.each {
+ type = existingCandidate.get('identifierType')
+ if (type == 'vimId') {
+ def cloudOwner = existingCandidate.get('cloudOwner')
+ def cloudRegionId = existingCandidate.get('identifiers')
+ existingCandidateJson = "{\n" +
+ " \"identifierType\": \"vimId\",\n" +
+ " \"cloudOwner\": \"${cloudOwner}\",\n" +
+ " \"identifiers\": [\"${cloudRegionId}\"]\n" +
+ " },"
+ sb.append(existingCandidateJson)
+ }
+ if (type == 'serviceInstanceId') {
+ def serviceInstanceId = existingCandidate.get('identifiers')
+ existingCandidateJson += "{\n" +
+ " \"identifierType\": \"serviceInstanceId\",\n" +
+ " \"identifiers\": [\"${serviceInstanceId}\"]\n" +
+ " },"
+ sb.append(existingCandidateJson)
+ }
+ }
+ if (existingCandidateJson != "") {
+ sb.setLength(sb.length() - 1)
+ candidatesJson = sb.append(",\n],")
+ }
+ }
+ if (excludedCandidates != null && excludedCandidates != {}) {
+ sb = new StringBuilder()
+ sb.append(",\n" +
+ " \"excludedCandidates\": [\n")
+ def excludedCandidateJson = ""
+ excludedCandidates.each {
+ type = excludedCandidate.get('identifierType')
+ if (type == 'vimId') {
+ def cloudOwner = excludedCandidate.get('cloudOwner')
+ def cloudRegionId = excludedCandidate.get('identifiers')
+ excludedCandidateJson = "{\n" +
+ " \"identifierType\": \"vimId\",\n" +
+ " \"cloudOwner\": \"${cloudOwner}\",\n" +
+ " \"identifiers\": [\"${cloudRegionId}\"]\n" +
+ " },"
+ sb.append(excludedCandidateJson)
+ }
+ if (type == 'serviceInstanceId') {
+ def serviceInstanceId = excludedCandidate.get('identifiers')
+ excludedCandidateJson += "{\n" +
+ " \"identifierType\": \"serviceInstanceId\",\n" +
+ " \"identifiers\": [\"${serviceInstanceId}\"]\n" +
+ " },"
+ sb.append(excludedCandidateJson)
+ }
+ }
+ if (excludedCandidateJson != "") {
+ sb.setLength(sb.length() - 1)
+ candidatesJson = sb.append(",\n],")
+ }
+ }
+ if (requiredCandidates != null && requiredCandidates != {}) {
+ sb = new StringBuilder()
+ sb.append(",\n" +
+ " \"requiredCandidates\": [\n")
+ def requiredCandidatesJson = ""
+ requiredCandidates.each {
+ type = requiredCandidate.get('identifierType')
+ if (type == 'vimId') {
+ def cloudOwner = requiredCandidate.get('cloudOwner')
+ def cloudRegionId = requiredCandidate.get('identifiers')
+ requiredCandidatesJson = "{\n" +
+ " \"identifierType\": \"vimId\",\n" +
+ " \"cloudOwner\": \"${cloudOwner}\",\n" +
+ " \"identifiers\": [\"${cloudRegionId}\"]\n" +
+ " },"
+ sb.append(requiredCandidatesJson)
+ }
+ if (type == 'serviceInstanceId') {
+ def serviceInstanceId = requiredCandidate.get('identifiers')
+ requiredCandidatesJson += "{\n" +
+ " \"identifierType\": \"serviceInstanceId\",\n" +
+ " \"identifiers\": [\"${serviceInstanceId}\"]\n" +
+ " },"
+ sb.append(requiredCandidatesJson)
+ }
+ }
+ if (requiredCandidatesJson != "") {
+ sb.setLength(sb.length() - 1)
+ candidatesJson = sb.append(",\n],")
+ }
+ }
+ if (candidatesJson != "") {candidatesJson = candidatesJson.substring(0, candidatesJson.length() - 1)}
+ return candidatesJson
+ }
+} \ No newline at end of file
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
index ab215c9949..88ed9fb330 100644
--- 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
@@ -96,7 +96,7 @@ class SNIROUtils{
String requestType = "initial"
List<Resource> resources = decomposition.getServiceResources()
for(Resource r:resources){
- HomingSolution currentSolution = r.getCurrentHomingSolution()
+ HomingSolution currentSolution = (HomingSolution) r.getCurrentHomingSolution()
if(currentSolution != null){
requestType = "speed changed"
}
diff --git a/bpmn/MSOCommonBPMN/src/main/groovy/org/openecomp/mso/bpmn/common/scripts/SniroHoming.groovy b/bpmn/MSOCommonBPMN/src/main/groovy/org/openecomp/mso/bpmn/common/scripts/SniroHoming.groovy
new file mode 100755
index 0000000000..3f534377d8
--- /dev/null
+++ b/bpmn/MSOCommonBPMN/src/main/groovy/org/openecomp/mso/bpmn/common/scripts/SniroHoming.groovy
@@ -0,0 +1,274 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.openecomp.mso.bpmn.common.scripts
+
+import org.camunda.bpm.engine.delegate.BpmnError
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+
+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.domain.VnfResource
+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 SniroHoming 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(DelegateExecution 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)
+
+ RESTConfig config = new RESTConfig(url)
+ RESTClient client = new RESTClient(config).addAuthorizationHeader(authHeader).addHeader("Content-Type", "application/json")
+ 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(DelegateExecution 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.placementInfo")
+
+ ServiceDecomposition decomposition = execution.getVariable("serviceDecomposition")
+ utils.log("DEBUG", "Service Decomposition: " + decomposition, isDebugEnabled)
+
+ List<Resource> 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"))
+ resource.getHomingSolution().setRehome(placement.getBoolean("isRehome"))
+ JSONArray assignmentArr = placement.getJSONArray("assignmentInfo")
+ Map<String, String> 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")) {
+ VnfResource vnf = new VnfResource()
+ vnf.setVnfHostname(assignmentMap.get("vnfHostName"))
+ resource.getHomingSolution().setVnf(vnf)
+ 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<String> entitlementPoolList = jsonUtil.StringArrayToList(execution, jsonEntitlementPoolList)
+ resource.getHomingSolution().getLicense().setEntitlementPoolList(entitlementPoolList)
+
+ String jsonLicenseKeyGroupList = jsonUtil.getJsonValue(license.toString(), "licenseKeyGroupList")
+ List<String> licenseKeyGroupList = jsonUtil.StringArrayToList(execution, jsonLicenseKeyGroupList)
+ resource.getHomingSolution().getLicense().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(DelegateExecution 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(DelegateExecution execution) {}
+
+}