From 8425c0116bd683792d4e6fe20b5a37f091d1cb86 Mon Sep 17 00:00:00 2001 From: Marcus G K Williams Date: Sat, 26 May 2018 09:43:56 -0700 Subject: Fix OOF Homing Interface - Update homing request build to send correct request to OOF - Use nfFunction field as resourceModuleName requires updating nfFunction fields during vcpeRestCust service creation in SDC - Fix No Solution Error from OOF - Made subscriber info and cloud info optional as OOF Homing does not require it - Update Homing Requests for AR to provide vgMuxInfra modelInfo instead of vgmuxAR modelInfo as required by OOF Issue-ID: SO-573 Change-Id: If1c41c81f387bb614be954d158d6cc4d9c48e2c8 Signed-off-by: Marcus G K Williams --- .../mso/bpmn/common/scripts/OofHoming.groovy | 25 +++-- .../mso/bpmn/common/scripts/OofUtils.groovy | 120 +++++++++++++++------ .../openecomp/mso/bpmn/common/OofHomingTest.java | 42 +++++--- .../BuildingBlocks/oofCallbackNoSolutionFound | 24 +++-- 4 files changed, 145 insertions(+), 66 deletions(-) (limited to 'bpmn/MSOCommonBPMN') 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 index f0f239b50f..d6576b7dce 100644 --- 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 @@ -73,6 +73,8 @@ class OofHoming extends AbstractServiceTaskProcessor { utils.log("DEBUG", "Incoming Request Id is: " + requestId, isDebugEnabled) String serviceInstanceId = execution.getVariable("serviceInstanceId") utils.log("DEBUG", "Incoming Service Instance Id is: " + serviceInstanceId, isDebugEnabled) + String serviceInstanceName = execution.getVariable("serviceInstanceName") + utils.log("DEBUG", "Incoming Service Instance Name is: " + serviceInstanceName, isDebugEnabled) ServiceDecomposition serviceDecomposition = execution.getVariable("serviceDecomposition") utils.log("DEBUG", "Incoming Service Decomposition is: " + serviceDecomposition, isDebugEnabled) String subscriberInfo = execution.getVariable("subscriberInfo") @@ -86,21 +88,24 @@ class OofHoming extends AbstractServiceTaskProcessor { if (isBlank(requestId) || isBlank(serviceInstanceId) || + isBlank(serviceInstanceName) || isBlank(serviceDecomposition.toString()) || - isBlank(subscriberInfo) || - isBlank(customerLocation.toString()) || - isBlank(cloudOwner) || - isBlank(cloudRegionId)) { + isBlank(customerLocation.toString())) { 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 = null + if (isBlank(subscriberInfo)) { + subscriber = new Subscriber("", "", "") + } 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 = new Subscriber(subId, subName, subCommonSiteId) } - Subscriber subscriber = new Subscriber(subId, subName, subCommonSiteId) //Authentication def authHeader = "" 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 index f07a477bb3..b61739f32c 100644 --- 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 @@ -1,19 +1,21 @@ package org.openecomp.mso.bpmn.common.scripts -import org.apache.commons.lang3.StringUtils -import org.camunda.bpm.engine.delegate.DelegateExecution; +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.AllottedResource 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 java.lang.reflect.Array + import static org.openecomp.mso.bpmn.common.scripts.GenericUtils.* class OofUtils { @@ -47,7 +49,7 @@ class OofUtils { String buildRequest(DelegateExecution execution, String requestId, ServiceDecomposition decomposition, - Subscriber subscriber, + Subscriber subscriber = null, Map customerLocation, ArrayList existingCandidates = null, ArrayList excludedCandidates = null, @@ -82,9 +84,14 @@ class OofUtils { String modelName = model.getModelName() String modelVersion = model.getModelVersion() //Subscriber Info - String subscriberId = subscriber.getGlobalId() - String subscriberName = subscriber.getName() - String commonSiteId = subscriber.getCommonSiteId() + String subscriberId = "" + String subscriberName = "" + String commonSiteId = "" + if (subscriber != null){ + subscriberId = subscriber.getGlobalId() + subscriberName = subscriber.getName() + commonSiteId = subscriber.getCommonSiteId() + } //Determine RequestType //TODO Figure out better way to determine this @@ -100,27 +107,39 @@ class OofUtils { //Demands String placementDemands = "" StringBuilder sb = new StringBuilder() - List resourceList = decomposition.getServiceAllottedResources() + List allottedResourceList = decomposition.getServiceAllottedResources() List vnfResourceList = decomposition.getServiceVnfs() - if (resourceList.isEmpty() || resourceList == null) { + if (allottedResourceList.isEmpty() || allottedResourceList == null) { utils.log("DEBUG", "Allotted Resources List is empty - will try to get service VNFs instead.", isDebugEnabled) - resourceList = decomposition.getServiceVnfs() + allottedResourceList = decomposition.getServiceVnfs() } - if (resourceList.isEmpty() || resourceList == null) { + if (allottedResourceList.isEmpty() || allottedResourceList == null) { utils.log("DEBUG", "Resources List is Empty", isDebugEnabled) } else { - for (Resource resource : resourceList) { - ModelInfo resourceModelInfo = resource.getModelInfo() + for (AllottedResource resource : allottedResourceList) { + utils.log("DEBUG", "Allotted Resource: " + resource.toString(), + isDebugEnabled) 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 resourceModuleName = resource.getNfFunction() + utils.log("DEBUG", "resourceModuleName: " + resourceModuleName, + isDebugEnabled) + def resourceModelInvariantId = "no-resourceModelInvariantId" + def resourceModelVersionId = "no-resourceModelVersionId" + + List modelIdLst = execution.getVariable("homingModelIds") + utils.log("DEBUG", "Incoming modelIdLst is: " + modelIdLst.toString(), isDebugEnabled) + for (Map modelId : modelIdLst ) + if (resourceModuleName == modelId.resourceModuleName) { + resourceModelInvariantId = modelId.resourceModelInvariantId + resourceModelVersionId = modelId.resourceModelVersionId + } + + def resourceModelName = "" //Optional + def resourceModelVersion = "" //Optional + def resourceModelType = "" //Optional def tenantId = "" //Optional def requiredCandidatesJson = "" @@ -130,22 +149,56 @@ class OofUtils { 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" + - "}," + " {\n" + + " \"resourceModuleName\": \"${resourceModuleName}\",\n" + + " \"serviceResourceId\": \"${serviceResourceId}\",\n" + + " \"tenantId\": \"${tenantId}\",\n" + + " \"resourceModelInfo\": {\n" + + " \"modelInvariantId\": \"${resourceModelInvariantId}\",\n" + + " \"modelVersionId\": \"${resourceModelVersionId}\",\n" + + " \"modelName\": \"${resourceModelName}\",\n" + + " \"modelType\": \"${resourceModelType}\",\n" + + " \"modelVersion\": \"${resourceModelVersion}\",\n" + + " \"modelCustomizationName\": \"\"\n" + + " }" + requiredCandidatesJson + "\n" + + " }," placementDemands = sb.append(demand) } + for (VnfResource vnfResource : vnfResourceList) { + utils.log("DEBUG", "VNF Resource: " + vnfResource.toString(), + isDebugEnabled) + ModelInfo vnfResourceModelInfo = vnfResource.getModelInfo() + def serviceResourceId = vnfResource.getResourceId() + def resourceModuleName = vnfResource.getNfFunction() + utils.log("DEBUG", "resourceModuleName: " + resourceModuleName, + isDebugEnabled) + def resourceModelInvariantId = vnfResourceModelInfo.getModelInvariantUuid() + def resourceModelName = vnfResourceModelInfo.getModelName() + def resourceModelVersion = vnfResourceModelInfo.getModelVersion() + def resourceModelVersionId = vnfResourceModelInfo.getModelUuid() + def resourceModelType = vnfResourceModelInfo.getModelType() + def tenantId = "" //Optional + def requiredCandidatesJson = "" + + + String placementDemand = + " {\n" + + " \"resourceModuleName\": \"${resourceModuleName}\",\n" + + " \"serviceResourceId\": \"${serviceResourceId}\",\n" + + " \"tenantId\": \"${tenantId}\",\n" + + " \"resourceModelInfo\": {\n" + + " \"modelInvariantId\": \"${resourceModelInvariantId}\",\n" + + " \"modelVersionId\": \"${resourceModelVersionId}\",\n" + + " \"modelName\": \"${resourceModelName}\",\n" + + " \"modelType\": \"${resourceModelType}\",\n" + + " \"modelVersion\": \"${resourceModelVersion}\",\n" + + " \"modelCustomizationName\": \"\"\n" + + " }" + requiredCandidatesJson + "\n" + + " }," + + placementDemands = sb.append(placementDemand) + } placementDemands = placementDemands.substring(0, placementDemands.length() - 1) } @@ -271,11 +324,14 @@ class OofUtils { } else { return } - } else if (JsonUtils.jsonElementExist(response, "requestError") == true) { + } else if (response.contains("error") || response.contains("Error") ) { 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("Unable to find any candidate for demand")) { + errorMessage = "OOF Async Callback Response contains error: Unable to find any candidate for " + + "demand *** Response: " + response.toString() } 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 diff --git a/bpmn/MSOCommonBPMN/src/test/java/org/openecomp/mso/bpmn/common/OofHomingTest.java b/bpmn/MSOCommonBPMN/src/test/java/org/openecomp/mso/bpmn/common/OofHomingTest.java index 283f3c6116..1f64fb55f8 100644 --- a/bpmn/MSOCommonBPMN/src/test/java/org/openecomp/mso/bpmn/common/OofHomingTest.java +++ b/bpmn/MSOCommonBPMN/src/test/java/org/openecomp/mso/bpmn/common/OofHomingTest.java @@ -41,6 +41,7 @@ import org.openecomp.mso.bpmn.mock.FileUtil; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.UUID; @@ -97,7 +98,7 @@ public class OofHomingTest extends WorkflowTest { List arList = new ArrayList(); AllottedResource ar = new AllottedResource(); ar.setResourceId("testResourceIdAR"); - ar.setResourceInstanceName("testARInstanceName"); + ar.setNfFunction("testARFunctionName"); ModelInfo arModel = new ModelInfo(); arModel.setModelCustomizationUuid("testModelCustomizationUuidAR"); arModel.setModelInvariantUuid("testModelInvariantIdAR"); @@ -108,7 +109,7 @@ public class OofHomingTest extends WorkflowTest { ar.setModelInfo(arModel); AllottedResource ar2 = new AllottedResource(); ar2.setResourceId("testResourceIdAR2"); - ar2.setResourceInstanceName("testAR2InstanceName"); + ar2.setNfFunction("testAR2FunctionName"); ModelInfo arModel2 = new ModelInfo(); arModel2.setModelCustomizationUuid("testModelCustomizationUuidAR2"); arModel2.setModelInvariantUuid("testModelInvariantIdAR2"); @@ -123,7 +124,7 @@ public class OofHomingTest extends WorkflowTest { List vnfList = new ArrayList(); VnfResource vnf = new VnfResource(); vnf.setResourceId("testResourceIdVNF"); - vnf.setResourceInstanceName("testVnfInstanceName"); + vnf.setNfFunction("testVnfFunctionName"); ArrayList flavors = new ArrayList<>(); CloudFlavor flavor1 = new CloudFlavor("flavorLabel1xxx", "vimFlavorxxx"); CloudFlavor flavor2 = new CloudFlavor("flavorLabel2xxx", "vimFlavorxxx"); @@ -478,9 +479,9 @@ public class OofHomingTest extends WorkflowTest { //Get Variables WorkflowException workflowException = (WorkflowException) getVariableFromHistory(businessKey, "WorkflowException"); - - assertEquals("WorkflowException[processKey=Homing,errorCode=400,errorMessage=No solution found " + - "for plan 08e1b8cf-144a-4bac-b293-d5e2eedc97e8]", workflowException.toString()); + Boolean errorMatch = workflowException.toString().contains("WorkflowException[processKey=Homing,errorCode=400,errorMessage=OOF Async Callback " + + "Response contains error: Unable to find any candidate for demand *** Response:"); + assert(errorMatch); } @Test @@ -546,7 +547,8 @@ public class OofHomingTest extends WorkflowTest { variables.put("customerLocation", customerLocation); variables.put("cloudOwner", "amazon"); variables.put("cloudRegionId", "TNZED"); - variables.put("isDebugLogEnabled", "true"); + variables.put("vgMuxInfraModelInvariantId", "testModelInvariantIdAR"); + variables.put("vgMuxInfraModelId", "testArModelUuid"); // variables.put("mso-request-id", "testRequestId"); variables.put("msoRequestId", "testRequestId"); variables.put("serviceInstanceId", "testServiceInstanceId123"); @@ -589,6 +591,8 @@ public class OofHomingTest extends WorkflowTest { variables.put("customerLocation", customerLocation); variables.put("cloudOwner", "amazon"); variables.put("cloudRegionId", "TNZED"); + variables.put("vgMuxInfraModelInvariantId", "testModelInvariantIdAR"); + variables.put("vgMuxInfraModelId", "testArModelUuid"); variables.put("isDebugLogEnabled", "true"); variables.put("msoRequestId", "testRequestId"); variables.put("serviceInstanceId", "testServiceInstanceId123"); @@ -609,6 +613,8 @@ public class OofHomingTest extends WorkflowTest { variables.put("customerLocation", customerLocation); variables.put("cloudOwner", "amazon"); variables.put("cloudRegionId", "TNZED"); + variables.put("vgMuxInfraModelInvariantId", "testModelInvariantIdAR"); + variables.put("vgMuxInfraModelId", "testArModelUuid"); variables.put("isDebugLogEnabled", "true"); // variables.put("mso-request-id", "testRequestId"); variables.put("msoRequestId", "testRequestId"); @@ -720,16 +726,20 @@ public class OofHomingTest extends WorkflowTest { "\"timeout\":600},\"placementInfo\":{\"requestParameters\":{\"customerLatitude\":" + "\"32.89748\",\"customerLongitude\":\"-97.040443\",\"customerName\":\"xyz\"},\"subscriberInfo\":" + "{\"globalSubscriberId\":\"SUB12_0322_DS_1201\",\"subscriberName\":\"SUB_12_0322_DS_1201\"," + - "\"subscriberCommonSiteId\":\"\"},\"placementDemands\":[{\"resourceModuleName\":\"ALLOTTED_RESOURCE\"" + + "\"subscriberCommonSiteId\":\"\"},\"placementDemands\":[{\"resourceModuleName\":\"testARFunctionName\"" + ",\"serviceResourceId\":\"testResourceIdAR\",\"tenantId\":" + - "\"\",\"resourceModelInfo\":{\"modelInvariantId\":\"testModelInvariantIdAR\"," + - "\"modelVersionId\":\"testARModelUuid\",\"modelName\":\"testModelNameAR\",\"modelType\":" + - "\"testModelTypeAR\",\"modelVersion\":\"testModelVersionAR\",\"modelCustomizationName\":\"\"}}," + - "{\"resourceModuleName\":\"ALLOTTED_RESOURCE\",\"serviceResourceId\":\"testResourceIdAR2\"," + - "\"tenantId\":\"\",\"resourceModelInfo\":{\"modelInvariantId\":\"testModelInvariantIdAR2\"," + - "\"modelVersionId\":\"testAr2ModelUuid\",\"modelName\":\"testModelNameAR2\"," + - "\"modelType\":\"testModelTypeAR2\",\"modelVersion\":\"testModelVersionAR2\"," + - "\"modelCustomizationName\":\"\"}}]},\"serviceInfo\":" + + "\"\",\"resourceModelInfo\":{\"modelInvariantId\":\"no-resourceModelInvariantId\"," + + "\"modelVersionId\":\"no-resourceModelVersionId\",\"modelName\":\"\",\"modelType\":" + + "\"\",\"modelVersion\":\"\",\"modelCustomizationName\":\"\"}}," + + "{\"resourceModuleName\":\"testAR2FunctionName\",\"serviceResourceId\":\"testResourceIdAR2\"," + + "\"tenantId\":\"\",\"resourceModelInfo\":{\"modelInvariantId\":\"no-resourceModelInvariantId\"," + + "\"modelVersionId\":\"no-resourceModelVersionId\",\"modelName\":\"\"," + + "\"modelType\":\"\",\"modelVersion\":\"\"," + + "\"modelCustomizationName\":\"\"}},{\"resourceModuleName\":\"testVnfFunctionName\",\"serviceResourceId\":\"" + + "testResourceIdVNF\",\"tenantId\":\"\",\"resourceModelInfo\":{\"modelInvariantId\"" + + ":\"testModelInvariantIdVNF\",\"modelVersionId\":\"testVnfModelUuid\",\"modelName\":\"" + + "testModelNameVNF\",\"modelType\":\"testModelTypeVNF\",\"modelVersion\":\"testModelVersionVNF\"" + + ",\"modelCustomizationName\":\"\"}}]},\"serviceInfo\":" + "{\"serviceInstanceId\":\"testServiceInstanceId123\"," + "\"serviceName\":\"testServiceName\",\"modelInfo\":{\"modelType\":\"\",\"modelInvariantId\":" + "\"testModelInvariantId\",\"modelVersionId\":\"testModelUuid\",\"modelName\":\"testModelName\"," + diff --git a/bpmn/MSOCommonBPMN/src/test/resources/__files/BuildingBlocks/oofCallbackNoSolutionFound b/bpmn/MSOCommonBPMN/src/test/resources/__files/BuildingBlocks/oofCallbackNoSolutionFound index 8bb29f0c0a..2024df401b 100644 --- a/bpmn/MSOCommonBPMN/src/test/resources/__files/BuildingBlocks/oofCallbackNoSolutionFound +++ b/bpmn/MSOCommonBPMN/src/test/resources/__files/BuildingBlocks/oofCallbackNoSolutionFound @@ -1,10 +1,18 @@ { - "solutions": { - "placementSolutions": [], - "licenseSolutions": [] - }, - "transactionId": "08e1b8cf-144a-4bac-b293-d5e2eedc97e8", - "requestId": "02c2e322-5839-4c97-9d46-0a5fa6bb642e", - "requestStatus": "completed", - "statusMessage": "No solution found for plan 08e1b8cf-144a-4bac-b293-d5e2eedc97e8" + "plans":[ + { + "name":"356fdb73-cef2-4dda-8865-31fd6733d6e4", + "message":"Unable to find any candidate for demand vGW", + "links":[ + [ + { + "rel":"self", + "href":"http://172.17.0.6:8091/v1/plans/1c15e194-6df5-43fe-a5ff-42e6093b8ddd" + } + ] + ], + "id":"1c15e194-6df5-43fe-a5ff-42e6093b8ddd", + "status":"error" + } + ] } \ No newline at end of file -- cgit 1.2.3-korg