summaryrefslogtreecommitdiffstats
path: root/models-interactions/model-actors/actor.so
diff options
context:
space:
mode:
Diffstat (limited to 'models-interactions/model-actors/actor.so')
-rw-r--r--models-interactions/model-actors/actor.so/src/main/java/org/onap/policy/controlloop/actor/so/SoActorServiceProvider.java314
-rw-r--r--models-interactions/model-actors/actor.so/src/test/java/org/onap/policy/controlloop/actor/so/SoActorServiceProviderTest.java111
-rw-r--r--models-interactions/model-actors/actor.so/src/test/resources/org/onap/policy/controlloop/actor/so/aai/AaiCqResponse.json673
-rw-r--r--models-interactions/model-actors/actor.so/src/test/resources/org/onap/policy/controlloop/actor/so/aai/AaiCqResponseMissing.json4
4 files changed, 1040 insertions, 62 deletions
diff --git a/models-interactions/model-actors/actor.so/src/main/java/org/onap/policy/controlloop/actor/so/SoActorServiceProvider.java b/models-interactions/model-actors/actor.so/src/main/java/org/onap/policy/controlloop/actor/so/SoActorServiceProvider.java
index 6d8fa4bd2..25b3a4eb8 100644
--- a/models-interactions/model-actors/actor.so/src/main/java/org/onap/policy/controlloop/actor/so/SoActorServiceProvider.java
+++ b/models-interactions/model-actors/actor.so/src/main/java/org/onap/policy/controlloop/actor/so/SoActorServiceProvider.java
@@ -28,6 +28,11 @@ import java.lang.reflect.Type;
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import org.onap.aai.domain.yang.CloudRegion;
+import org.onap.aai.domain.yang.GenericVnf;
+import org.onap.aai.domain.yang.ServiceInstance;
+import org.onap.aai.domain.yang.Tenant;
+import org.onap.policy.aai.AaiCqResponse;
import org.onap.policy.aai.AaiNqExtraProperty;
import org.onap.policy.aai.AaiNqInventoryResponseItem;
import org.onap.policy.aai.AaiNqResponseWrapper;
@@ -62,10 +67,10 @@ public class SoActorServiceProvider implements Actor {
private static final String RECIPE_VF_MODULE_CREATE = "VF Module Create";
private static final String RECIPE_VF_MODULE_DELETE = "VF Module Delete";
- private static final ImmutableList<String> recipes = ImmutableList.of(RECIPE_VF_MODULE_CREATE,
- RECIPE_VF_MODULE_DELETE);
- private static final ImmutableMap<String, List<String>> targets = new ImmutableMap.Builder<String, List<String>>()
- .put(RECIPE_VF_MODULE_CREATE, ImmutableList.of(TARGET_VFC))
+ private static final ImmutableList<String> recipes =
+ ImmutableList.of(RECIPE_VF_MODULE_CREATE, RECIPE_VF_MODULE_DELETE);
+ private static final ImmutableMap<String, List<String>> targets =
+ new ImmutableMap.Builder<String, List<String>>().put(RECIPE_VF_MODULE_CREATE, ImmutableList.of(TARGET_VFC))
.put(RECIPE_VF_MODULE_DELETE, ImmutableList.of(TARGET_VFC)).build();
// name of request parameters within policy payload
@@ -109,19 +114,17 @@ public class SoActorServiceProvider implements Actor {
}
/**
- * Constructs a SO request conforming to the lcm API. The actual request is
- * constructed and then placed in a wrapper object used to send through DMAAP.
+ * Constructs a SO request conforming to the lcm API. The actual request is constructed and then placed in a wrapper
+ * object used to send through DMAAP.
*
* @param onset the event that is reporting the alert for policy to perform an action
- * @param operation the control loop operation specifying the actor, operation,
- * target, etc.
- * @param policy the policy the was specified from the yaml generated by CLAMP or
- * through the Policy GUI/API
+ * @param operation the control loop operation specifying the actor, operation, target, etc.
+ * @param policy the policy the was specified from the yaml generated by CLAMP or through the Policy GUI/API
* @param aaiResponseWrapper wrapper for AAI vserver named-query response
* @return a SO request conforming to the lcm API using the DMAAP wrapper
*/
public SoRequest constructRequest(VirtualControlLoopEvent onset, ControlLoopOperation operation, Policy policy,
- AaiNqResponseWrapper aaiResponseWrapper) {
+ AaiNqResponseWrapper aaiResponseWrapper) {
if (!SO_ACTOR.equals(policy.getActor()) || !recipes().contains(policy.getRecipe())) {
return null;
}
@@ -138,10 +141,10 @@ public class SoActorServiceProvider implements Actor {
// Extract the items we're interested in from the response
try {
vnfItem = aaiResponseWrapper.getAaiNqResponse().getInventoryResponseItems().get(0).getItems()
- .getInventoryResponseItems().get(0);
+ .getInventoryResponseItems().get(0);
} catch (Exception e) {
logger.error("VNF Item not found in AAI response {}", Serialization.gsonPretty.toJson(aaiResponseWrapper),
- e);
+ e);
return null;
}
@@ -149,16 +152,16 @@ public class SoActorServiceProvider implements Actor {
vnfServiceItem = vnfItem.getItems().getInventoryResponseItems().get(0);
} catch (Exception e) {
logger.error("VNF Service Item not found in AAI response {}",
- Serialization.gsonPretty.toJson(aaiResponseWrapper), e);
+ Serialization.gsonPretty.toJson(aaiResponseWrapper), e);
return null;
}
try {
tenantItem = aaiResponseWrapper.getAaiNqResponse().getInventoryResponseItems().get(0).getItems()
- .getInventoryResponseItems().get(1);
+ .getInventoryResponseItems().get(1);
} catch (Exception e) {
logger.error("Tenant Item not found in AAI response {}",
- Serialization.gsonPretty.toJson(aaiResponseWrapper), e);
+ Serialization.gsonPretty.toJson(aaiResponseWrapper), e);
return null;
}
@@ -175,8 +178,7 @@ public class SoActorServiceProvider implements Actor {
// Construct SO Request for a policy's recipe
if (RECIPE_VF_MODULE_CREATE.equals(policy.getRecipe())) {
- return constructCreateRequest(aaiResponseWrapper, policy, tenantItem, vnfItem, vnfServiceItem,
- soModelInfo);
+ return constructCreateRequest(aaiResponseWrapper, policy, tenantItem, vnfItem, vnfServiceItem, soModelInfo);
} else if (RECIPE_VF_MODULE_DELETE.equals(policy.getRecipe())) {
return constructDeleteRequest(tenantItem, vnfItem, vnfServiceItem, soModelInfo, policy);
} else {
@@ -187,12 +189,9 @@ public class SoActorServiceProvider implements Actor {
private SoModelInfo prepareSoModelInfo(Policy policy) {
SoModelInfo soModelInfo = new SoModelInfo();
- if ((policy.getTarget() != null
- && (policy.getTarget().getModelCustomizationId() != null))
- && (policy.getTarget().getModelInvariantId() != null)
- && (policy.getTarget().getModelName() != null)
- && (policy.getTarget().getModelVersion() != null)
- && (policy.getTarget().getModelVersionId() != null)) {
+ if ((policy.getTarget() != null && (policy.getTarget().getModelCustomizationId() != null))
+ && (policy.getTarget().getModelInvariantId() != null) && (policy.getTarget().getModelName() != null)
+ && (policy.getTarget().getModelVersion() != null) && (policy.getTarget().getModelVersionId() != null)) {
soModelInfo.setModelCustomizationId(policy.getTarget().getModelCustomizationId());
soModelInfo.setModelInvariantId(policy.getTarget().getModelInvariantId());
@@ -210,17 +209,16 @@ public class SoActorServiceProvider implements Actor {
* Construct SO request to create vf-module.
*
* @param aaiResponseWrapper the AAI response containing the VF modules
- * @param policy the policy
- * @param tenantItem tenant item from A&AI named-query response
- * @param vnfItem vnf item from A&AI named-query response
- * @param vnfServiceItem vnf service item from A&AI named-query response
- * @param vfModuleItem vf module item from A&AI named-query response
+ * @param policy the policy
+ * @param tenantItem tenant item from A&AI named-query response
+ * @param vnfItem vnf item from A&AI named-query response
+ * @param vnfServiceItem vnf service item from A&AI named-query response
+ * @param vfModuleItem vf module item from A&AI named-query response
* @return SO create vf-module request
*/
private SoRequest constructCreateRequest(AaiNqResponseWrapper aaiResponseWrapper, Policy policy,
- AaiNqInventoryResponseItem tenantItem, AaiNqInventoryResponseItem vnfItem,
- AaiNqInventoryResponseItem vnfServiceItem,
- SoModelInfo vfModuleItem) {
+ AaiNqInventoryResponseItem tenantItem, AaiNqInventoryResponseItem vnfItem,
+ AaiNqInventoryResponseItem vnfServiceItem, SoModelInfo vfModuleItem) {
SoRequest request = new SoRequest();
request.setOperationType(SoOperationType.SCALE_OUT);
//
@@ -283,9 +281,8 @@ public class SoActorServiceProvider implements Actor {
.setModelVersionId(prop.getPropertyValue());
}
}
- relatedInstanceListElement2.getRelatedInstance().getModelInfo()
- .setModelCustomizationName(vnfItem.getGenericVnf().getVnfType()
- .substring(vnfItem.getGenericVnf().getVnfType().lastIndexOf('/') + 1));
+ relatedInstanceListElement2.getRelatedInstance().getModelInfo().setModelCustomizationName(vnfItem
+ .getGenericVnf().getVnfType().substring(vnfItem.getGenericVnf().getVnfType().lastIndexOf('/') + 1));
relatedInstanceListElement2.getRelatedInstance().getModelInfo()
.setModelCustomizationId(vnfItem.getGenericVnf().getModelCustomizationId());
@@ -300,8 +297,8 @@ public class SoActorServiceProvider implements Actor {
buildConfigurationParameters(policy, request.getRequestDetails());
// Save the instance IDs for the VNF and service to static fields
// vfModuleId is not required for the create vf-module
- preserveInstanceIds(vnfItem.getGenericVnf().getVnfId(), vnfServiceItem.getServiceInstance()
- .getServiceInstanceId(), null);
+ preserveInstanceIds(vnfItem.getGenericVnf().getVnfId(),
+ vnfServiceItem.getServiceInstance().getServiceInstanceId(), null);
if (logger.isDebugEnabled()) {
logger.debug("Constructed SO request: {}", Serialization.gsonPretty.toJson(request));
}
@@ -311,14 +308,14 @@ public class SoActorServiceProvider implements Actor {
/**
* Construct SO request to delete vf-module.
*
- * @param tenantItem tenant item from A&AI named-query response
- * @param vnfItem vnf item from A&AI named-query response
- * @param vnfServiceItem vnf service item from A&AI named-query response
- * @param vfModuleItem vf module item from A&AI named-query response
+ * @param tenantItem tenant item from A&AI named-query response
+ * @param vnfItem vnf item from A&AI named-query response
+ * @param vnfServiceItem vnf service item from A&AI named-query response
+ * @param vfModuleItem vf module item from A&AI named-query response
* @return SO delete vf-module request
*/
- private SoRequest constructDeleteRequest(AaiNqInventoryResponseItem tenantItem, AaiNqInventoryResponseItem
- vnfItem, AaiNqInventoryResponseItem vnfServiceItem, SoModelInfo vfModuleItem, Policy policy) {
+ private SoRequest constructDeleteRequest(AaiNqInventoryResponseItem tenantItem, AaiNqInventoryResponseItem vnfItem,
+ AaiNqInventoryResponseItem vnfServiceItem, SoModelInfo vfModuleItem, Policy policy) {
SoRequest request = new SoRequest();
request.setOperationType(SoOperationType.DELETE_VF_MODULE);
request.setRequestDetails(new SoRequestDetails());
@@ -332,8 +329,8 @@ public class SoActorServiceProvider implements Actor {
// requestInfo
request.getRequestDetails().setRequestInfo(constructRequestInfo());
// Save the instance IDs for the VNF, service and vfModule to static fields
- preserveInstanceIds(vnfItem.getGenericVnf().getVnfId(), vnfServiceItem.getServiceInstance()
- .getServiceInstanceId(), null);
+ preserveInstanceIds(vnfItem.getGenericVnf().getVnfId(),
+ vnfServiceItem.getServiceInstance().getServiceInstanceId(), null);
if (logger.isDebugEnabled()) {
logger.debug("Constructed SO request: {}", Serialization.gsonPretty.toJson(request));
@@ -363,14 +360,13 @@ public class SoActorServiceProvider implements Actor {
private SoCloudConfiguration constructCloudConfiguration(AaiNqInventoryResponseItem tenantItem) {
SoCloudConfiguration cloudConfiguration = new SoCloudConfiguration();
cloudConfiguration.setTenantId(tenantItem.getTenant().getTenantId());
- cloudConfiguration.setLcpCloudRegionId(tenantItem.getItems().getInventoryResponseItems().get(0)
- .getCloudRegion().getCloudRegionId());
+ cloudConfiguration.setLcpCloudRegionId(
+ tenantItem.getItems().getInventoryResponseItems().get(0).getCloudRegion().getCloudRegionId());
return cloudConfiguration;
}
/**
- * This method is needed to get the serviceInstanceId and vnfInstanceId which is used
- * in the asyncSORestCall.
+ * This method is needed to get the serviceInstanceId and vnfInstanceId which is used in the asyncSORestCall.
*
* @param requestId the request Id
* @param callback callback method
@@ -379,20 +375,19 @@ public class SoActorServiceProvider implements Actor {
* @param user username
* @param password password
*/
- public static void sendRequest(String requestId, SoManager.SoCallback callback, Object request,
- String url, String user, String password) {
+ public static void sendRequest(String requestId, SoManager.SoCallback callback, Object request, String url,
+ String user, String password) {
SoManager soManager = new SoManager(url, user, password);
soManager.asyncSoRestCall(requestId, callback, lastServiceItemServiceInstanceId, lastVNFItemVnfId,
lastVfModuleItemVfModuleInstanceId, (SoRequest) request);
}
/**
- * Find the base or non base VF module item in an AAI response.
- * If there is more than one item, then the <i>last</i> item is returned
+ * Find the base or non base VF module item in an AAI response. If there is more than one item, then the <i>last</i>
+ * item is returned
*
* @param aaiResponseWrapper the AAI response containing the VF modules
- * @param baseFlag true if we are searching for the base, false if we are searching
- * for the non base
+ * @param baseFlag true if we are searching for the base, false if we are searching for the non base
* @return the base or non base VF module item or null if the module was not found
*/
private AaiNqInventoryResponseItem findVfModule(AaiNqResponseWrapper aaiResponseWrapper, boolean baseFlag) {
@@ -445,17 +440,220 @@ public class SoActorServiceProvider implements Actor {
}
/**
- * This method is called to remember the last service instance ID, VNF Item VNF ID and vf module ID.
- * Note these fields are static, beware for multithreaded deployments
+ * This method is called to remember the last service instance ID, VNF Item VNF ID and vf module ID. Note these
+ * fields are static, beware for multithreaded deployments
*
* @param vnfInstanceId update the last VNF instance ID to this value
* @param serviceInstanceId update the last service instance ID to this value
* @param vfModuleId update the vfModule instance ID to this value
*/
private static void preserveInstanceIds(final String vnfInstanceId, final String serviceInstanceId,
- final String vfModuleId) {
+ final String vfModuleId) {
lastVNFItemVnfId = vnfInstanceId;
lastServiceItemServiceInstanceId = serviceInstanceId;
lastVfModuleItemVfModuleInstanceId = vfModuleId;
}
+
+ /**
+ * Constructs a SO request conforming to the lcm API. The actual request is constructed and then placed in a wrapper
+ * object used to send through DMAAP.
+ *
+ * @param onset the event that is reporting the alert for policy to perform an action
+ * @param operation the control loop operation specifying the actor, operation, target, etc.
+ * @param policy the policy the was specified from the yaml generated by CLAMP or through the Policy GUI/API
+ * @param aaiCqResponse response from A&AI custom query
+ * @return a SO request conforming to the lcm API using the DMAAP wrapper
+ */
+ public SoRequest constructRequestCq(VirtualControlLoopEvent onset, ControlLoopOperation operation, Policy policy,
+ AaiCqResponse aaiCqResponse) {
+ if (!SO_ACTOR.equals(policy.getActor()) || !recipes().contains(policy.getRecipe())) {
+ return null;
+ }
+
+ // A&AI named query should have been performed by now. If not, return null
+ if (aaiCqResponse == null) {
+ return null;
+ }
+
+ GenericVnf vnfItem;
+ ServiceInstance vnfServiceItem;
+ Tenant tenantItem;
+ CloudRegion cloudRegionItem;
+
+ // Extract the items we're interested in from the response
+ try {
+ vnfItem = aaiCqResponse.getDefaultGenericVnf();
+ } catch (Exception e) {
+ logger.error("VNF Item not found in AAI response {}", Serialization.gsonPretty.toJson(aaiCqResponse), e);
+ return null;
+ }
+
+ try {
+ vnfServiceItem = aaiCqResponse.getServiceInstance();
+ } catch (Exception e) {
+ logger.error("VNF Service Item not found in AAI response {}",
+ Serialization.gsonPretty.toJson(aaiCqResponse), e);
+ return null;
+ }
+
+ try {
+ tenantItem = aaiCqResponse.getDefaultTenant();
+ } catch (Exception e) {
+ logger.error("Tenant Item not found in AAI response {}", Serialization.gsonPretty.toJson(aaiCqResponse), e);
+ return null;
+ }
+
+ try {
+ cloudRegionItem = aaiCqResponse.getDefaultCloudRegion();
+ } catch (Exception e) {
+ logger.error("Tenant Item not found in AAI response {}", Serialization.gsonPretty.toJson(aaiCqResponse), e);
+ return null;
+ }
+
+ SoModelInfo soModelInfo = prepareSoModelInfo(policy);
+
+ // Report the error vf module is not found
+ if (soModelInfo == null) {
+ logger.error("vf module is not found.");
+ return null;
+ }
+
+ // Construct SO Request for a policy's recipe
+ if (RECIPE_VF_MODULE_CREATE.equals(policy.getRecipe())) {
+ return constructCreateRequestCq(aaiCqResponse, policy, tenantItem, vnfItem, vnfServiceItem, soModelInfo,
+ cloudRegionItem);
+ } else if (RECIPE_VF_MODULE_DELETE.equals(policy.getRecipe())) {
+ return constructDeleteRequestCq(tenantItem, vnfItem, vnfServiceItem, soModelInfo, policy, cloudRegionItem);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Construct the So request, based on Custom Query response from A&AI.
+ *
+ * @param aaiCqResponse Custom query response from A&AI
+ * @param policy policy information
+ * @param tenantItem Tenant from CQ response
+ * @param vnfItem Generic VNF from CQ response
+ * @param vnfServiceItem Service Instance from CQ response
+ * @param vfModuleItem VF Module from CustomQuery response
+ * @param cloudRegionItem Cloud Region from Custom query response
+ * @return SoRequest well formed So Request
+ */
+ private SoRequest constructCreateRequestCq(AaiCqResponse aaiCqResponse, Policy policy, Tenant tenantItem,
+ GenericVnf vnfItem, ServiceInstance vnfServiceItem, SoModelInfo vfModuleItem, CloudRegion cloudRegionItem) {
+ SoRequest request = new SoRequest();
+ request.setOperationType(SoOperationType.SCALE_OUT);
+ //
+ //
+ // Do NOT send So the requestId, they do not support this field
+ //
+ request.setRequestDetails(new SoRequestDetails());
+ request.getRequestDetails().setRequestParameters(new SoRequestParameters());
+ request.getRequestDetails().getRequestParameters().setUserParams(null);
+
+ // cloudConfiguration
+ request.getRequestDetails().setCloudConfiguration(constructCloudConfigurationCq(tenantItem, cloudRegionItem));
+ // modelInfo
+ request.getRequestDetails().setModelInfo(vfModuleItem);
+
+ // requestInfo
+ request.getRequestDetails().setRequestInfo(constructRequestInfo());
+ String vfModuleName = aaiCqResponse.getDefaultVfModule().getVfModuleName();
+ request.getRequestDetails().getRequestInfo().setInstanceName(vfModuleName);
+
+ // relatedInstanceList
+ SoRelatedInstanceListElement relatedInstanceListElement1 = new SoRelatedInstanceListElement();
+ SoRelatedInstanceListElement relatedInstanceListElement2 = new SoRelatedInstanceListElement();
+ relatedInstanceListElement1.setRelatedInstance(new SoRelatedInstance());
+ relatedInstanceListElement2.setRelatedInstance(new SoRelatedInstance());
+
+ // Service Item (Note that Model Name and Model Version are not available in A&AI schema for ServiceInstance)
+ relatedInstanceListElement1.getRelatedInstance().setInstanceId(vnfServiceItem.getServiceInstanceId());
+ relatedInstanceListElement1.getRelatedInstance().setModelInfo(new SoModelInfo());
+ relatedInstanceListElement1.getRelatedInstance().getModelInfo().setModelType("service");
+ relatedInstanceListElement1.getRelatedInstance().getModelInfo()
+ .setModelInvariantId(vnfServiceItem.getModelInvariantId());
+ relatedInstanceListElement1.getRelatedInstance().getModelInfo()
+ .setModelVersionId(vnfServiceItem.getModelVersionId());
+
+
+ // VNF Item (Note that Model Name, Model Version, and Model Customization Name are not available in A&AI schema
+ // for Generic VNF)
+ relatedInstanceListElement2.getRelatedInstance().setInstanceId(vnfItem.getVnfId());
+ relatedInstanceListElement2.getRelatedInstance().setModelInfo(new SoModelInfo());
+ relatedInstanceListElement2.getRelatedInstance().getModelInfo().setModelType("vnf");
+ relatedInstanceListElement2.getRelatedInstance().getModelInfo()
+ .setModelInvariantId(vnfItem.getModelInvariantId());
+ relatedInstanceListElement2.getRelatedInstance().getModelInfo().setModelVersionId(vnfItem.getModelVersionId());
+ relatedInstanceListElement2.getRelatedInstance().getModelInfo()
+ .setModelCustomizationId(vnfItem.getModelCustomizationId());
+
+ // Insert the Service Item and VNF Item
+ request.getRequestDetails().getRelatedInstanceList().add(relatedInstanceListElement1);
+ request.getRequestDetails().getRelatedInstanceList().add(relatedInstanceListElement2);
+
+ // Request Parameters
+ buildRequestParameters(policy, request.getRequestDetails());
+
+ // Configuration Parameters
+ buildConfigurationParameters(policy, request.getRequestDetails());
+ // Save the instance IDs for the VNF and service to static fields
+ // vfModuleId is not required for the create vf-module
+ preserveInstanceIds(vnfItem.getVnfId(), vnfServiceItem.getServiceInstanceId(), null);
+ if (logger.isDebugEnabled()) {
+ logger.debug("Constructed SO request: {}", Serialization.gsonPretty.toJson(request));
+ }
+ return request;
+ }
+
+ /**
+ * constructs delete request for So.
+ *
+ * @param tenantItem Tenant from A&AI CQ request
+ * @param vnfItem Generic VNF from A&AI CQ request
+ * @param vnfServiceItem ServiceInstance from A&AI CQ request
+ * @param vfModuleItem VFModule from A&AI CQ request
+ * @param policy policy information
+ * @param cloudRegionItem CloudRegion from A&AI CQ request
+ * @return SoRequest deleted
+ */
+ private SoRequest constructDeleteRequestCq(Tenant tenantItem, GenericVnf vnfItem, ServiceInstance vnfServiceItem,
+ SoModelInfo vfModuleItem, Policy policy, CloudRegion cloudRegionItem) {
+ SoRequest request = new SoRequest();
+ request.setOperationType(SoOperationType.DELETE_VF_MODULE);
+ request.setRequestDetails(new SoRequestDetails());
+ request.getRequestDetails().setRelatedInstanceList(null);
+ request.getRequestDetails().setConfigurationParameters(null);
+
+ // cloudConfiguration
+ request.getRequestDetails().setCloudConfiguration(constructCloudConfigurationCq(tenantItem, cloudRegionItem));
+ // modelInfo
+ request.getRequestDetails().setModelInfo(prepareSoModelInfo(policy));
+ // requestInfo
+ request.getRequestDetails().setRequestInfo(constructRequestInfo());
+ // Save the instance IDs for the VNF, service and vfModule to static fields
+ preserveInstanceIds(vnfItem.getVnfId(), vnfServiceItem.getServiceInstanceId(), null);
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("Constructed SO request: {}", Serialization.gsonPretty.toJson(request));
+ }
+ return request;
+ }
+
+
+ /**
+ * Construct cloudConfiguration for the SO requestDetails. Overridden for custom query.
+ *
+ * @param tenantItem tenant item from A&AI named-query response
+ * @return SO cloud configuration
+ */
+ private SoCloudConfiguration constructCloudConfigurationCq(Tenant tenantItem, CloudRegion cloudRegionItem) {
+ SoCloudConfiguration cloudConfiguration = new SoCloudConfiguration();
+ cloudConfiguration.setTenantId(tenantItem.getTenantId());
+ cloudConfiguration.setLcpCloudRegionId(cloudRegionItem.getCloudRegionId());
+ return cloudConfiguration;
+ }
+
}
diff --git a/models-interactions/model-actors/actor.so/src/test/java/org/onap/policy/controlloop/actor/so/SoActorServiceProviderTest.java b/models-interactions/model-actors/actor.so/src/test/java/org/onap/policy/controlloop/actor/so/SoActorServiceProviderTest.java
index 8b4bcf20a..7807e104d 100644
--- a/models-interactions/model-actors/actor.so/src/test/java/org/onap/policy/controlloop/actor/so/SoActorServiceProviderTest.java
+++ b/models-interactions/model-actors/actor.so/src/test/java/org/onap/policy/controlloop/actor/so/SoActorServiceProviderTest.java
@@ -36,7 +36,9 @@ import java.util.Map;
import java.util.TreeMap;
import java.util.UUID;
import org.apache.commons.io.IOUtils;
+import org.eclipse.persistence.exceptions.JAXBException;
import org.junit.Test;
+import org.onap.policy.aai.AaiCqResponse;
import org.onap.policy.aai.AaiNqResponse;
import org.onap.policy.aai.AaiNqResponseWrapper;
import org.onap.policy.controlloop.ControlLoopOperation;
@@ -113,13 +115,13 @@ public class SoActorServiceProviderTest {
// response has no base VF module
assertNull(new SoActorServiceProvider().constructRequest(onset, operation, policy,
- loadAaiResponse(onset, "aai/AaiNqResponse-NoBase.json")));
+ loadAaiResponse(onset, "aai/AaiNqResponse-NoBase.json")));
policy.setTarget(null);
// response has no non-base VF modules (other than the "dummy")
assertNull(new SoActorServiceProvider().constructRequest(onset, operation, policy,
- loadAaiResponse(onset, "aai/AaiNqResponse-NoNonBase.json")));
+ loadAaiResponse(onset, "aai/AaiNqResponse-NoNonBase.json")));
instantiateTarget(policy);
policy.setRecipe(VF_MODULE_DELETE);
@@ -135,12 +137,12 @@ public class SoActorServiceProviderTest {
// null tenant
aaiNqResp.getAaiNqResponse().getInventoryResponseItems().get(0).getItems().getInventoryResponseItems()
- .remove(1);
+ .remove(1);
assertNull(new SoActorServiceProvider().constructRequest(onset, operation, policy, aaiNqResp));
// null service item
aaiNqResp.getAaiNqResponse().getInventoryResponseItems().get(0).getItems().getInventoryResponseItems().get(0)
- .setItems(null);
+ .setItems(null);
assertNull(new SoActorServiceProvider().constructRequest(onset, operation, policy, aaiNqResp));
// null response
@@ -182,6 +184,107 @@ public class SoActorServiceProviderTest {
assertEquals(1, sp.recipeTargets(VF_MODULE_CREATE).size());
}
+ @Test
+ public void testConstructRequestCq() throws Exception {
+ VirtualControlLoopEvent onset = new VirtualControlLoopEvent();
+ final ControlLoopOperation operation = new ControlLoopOperation();
+ final AaiCqResponse aaiCqResp = loadAaiResponseCq("aai/AaiCqResponse.json");
+ final AaiCqResponse aaiCqRespMissing = loadAaiResponseCq("aai/AaiCqResponseMissing.json");
+ final UUID requestId = UUID.randomUUID();
+ onset.setRequestId(requestId);
+
+ Policy policy = new Policy();
+ policy.setActor("Dorothy");
+ policy.setRecipe("GoToOz");
+
+ instantiateTarget(policy);
+
+ assertNull(new SoActorServiceProvider().constructRequestCq(onset, operation, policy, aaiCqResp));
+
+ policy.setActor("SO");
+ assertNull(new SoActorServiceProvider().constructRequestCq(onset, operation, policy, aaiCqResp));
+
+ policy.setRecipe(VF_MODULE_CREATE);
+
+ // empty policy payload
+ SoRequest request = new SoActorServiceProvider().constructRequestCq(onset, operation, policy, aaiCqResp);
+ assertNotNull(request);
+
+ assertEquals("TestVM-0201-2", request.getRequestDetails().getRequestInfo().getInstanceName());
+ assertEquals("policy", request.getRequestDetails().getRequestInfo().getRequestorId());
+ assertEquals("cr-16197-01-as988q", request.getRequestDetails().getCloudConfiguration().getLcpCloudRegionId());
+
+ // non-empty policy payload
+ policy.setPayload(makePayload());
+ request = new SoActorServiceProvider().constructRequestCq(onset, operation, policy, aaiCqResp);
+ assertNotNull(request);
+ assertEquals(true, request.getRequestDetails().getRequestParameters().isUsePreload());
+ assertEquals("avalue", request.getRequestDetails().getRequestParameters().getUserParams().get(0).get("akey"));
+ assertEquals(1, request.getRequestDetails().getConfigurationParameters().size());
+ assertEquals("cvalue", request.getRequestDetails().getConfigurationParameters().get(0).get("ckey"));
+
+ // payload with config, but no request params
+ policy.setPayload(makePayload());
+ policy.getPayload().remove(SoActorServiceProvider.REQ_PARAM_NM);
+ request = new SoActorServiceProvider().constructRequestCq(onset, operation, policy, aaiCqResp);
+ assertNotNull(request);
+ assertNull(request.getRequestDetails().getRequestParameters());
+ assertNotNull(request.getRequestDetails().getConfigurationParameters());
+
+ // payload with request, but no config params
+ policy.setPayload(makePayload());
+ policy.getPayload().remove(SoActorServiceProvider.CONFIG_PARAM_NM);
+ request = new SoActorServiceProvider().constructRequestCq(onset, operation, policy, aaiCqResp);
+ assertNotNull(request);
+ assertNotNull(request.getRequestDetails().getRequestParameters());
+ assertNull(request.getRequestDetails().getConfigurationParameters());
+
+ // null response
+ assertNull(new SoActorServiceProvider().constructRequestCq(onset, operation, policy, null));
+
+
+ policy.setTarget(null);
+
+ // response has no non-base VF modules (other than the "dummy")
+ assertNull(new SoActorServiceProvider().constructRequestCq(onset, operation, policy,
+ loadAaiResponseCq("aai/AaiCqResponse.json")));
+
+ instantiateTarget(policy);
+ policy.setRecipe(VF_MODULE_DELETE);
+ SoRequest deleteRequest = new SoActorServiceProvider().constructRequestCq(onset, operation, policy, aaiCqResp);
+ assertNotNull(deleteRequest);
+ assertEquals(SoOperationType.DELETE_VF_MODULE, deleteRequest.getOperationType());
+
+ /*
+ * NOTE: The remaining tests must be done in order
+ */
+
+ policy.setRecipe(VF_MODULE_CREATE);
+
+ // null tenant
+ assertNull(new SoActorServiceProvider().constructRequestCq(onset, operation, policy, aaiCqRespMissing));
+
+ // null service item
+ assertNull(new SoActorServiceProvider().constructRequestCq(onset, operation, policy, aaiCqRespMissing));
+
+ assertNull(new SoActorServiceProvider().constructRequestCq(onset, operation, policy, null));
+ }
+
+ /**
+ * Reads an AAI vserver named-query response from a file.
+ *
+ * @param fileName name of the file containing the JSON response
+ * @return output from the AAI vserver named-query
+ * @throws IOException if the file cannot be read
+ * @throws JAXBException throws JAXBException
+ */
+ private AaiCqResponse loadAaiResponseCq(String fileName) throws IOException, JAXBException {
+ String resp = IOUtils.toString(getClass().getResource(fileName), StandardCharsets.UTF_8);
+ return new AaiCqResponse(resp);
+ }
+
+
+
/**
* Creates a policy payload containing request & configuration parameters.
*
diff --git a/models-interactions/model-actors/actor.so/src/test/resources/org/onap/policy/controlloop/actor/so/aai/AaiCqResponse.json b/models-interactions/model-actors/actor.so/src/test/resources/org/onap/policy/controlloop/actor/so/aai/AaiCqResponse.json
new file mode 100644
index 000000000..63d6f79ac
--- /dev/null
+++ b/models-interactions/model-actors/actor.so/src/test/resources/org/onap/policy/controlloop/actor/so/aai/AaiCqResponse.json
@@ -0,0 +1,673 @@
+{
+ "results": [
+ {
+ "vserver": {
+ "vserver-id": "e7f1db09-ff78-44fc-b256-69095c5556fb",
+ "vserver-name": "vfw-vm-0201-2",
+ "vserver-name2": "vfw-vm-0201-2",
+ "prov-status": "ACTIVE",
+ "vserver-selflink": "http://ecompctl1.research.att.com:8774/v2/3f2aaef74ecb4b19b35e26d0849fe9a2/servers/e7f1db09-ff78-44fc-b256-69095c5556fb",
+ "in-maint": false,
+ "is-closed-loop-disabled": false,
+ "resource-version": "1549553422524",
+ "relationship-list": {
+ "relationship": [
+ {
+ "related-to": "generic-vnf",
+ "related-link": "/aai/v11/network/generic-vnfs/generic-vnf/17044ef4-e7f3-46a1-af03-e2aa562f23ac",
+ "relationship-data": [
+ {
+ "relationship-key": "generic-vnf.vnf-id",
+ "relationship-value": "17044ef4-e7f3-46a1-af03-e2aa562f23ac"
+ }
+ ],
+ "related-to-property": [
+ {
+ "property-key": "generic-vnf.vnf-name",
+ "property-value": "TestVM-Vnf-0201-1"
+ }
+ ]
+ },
+ {
+ "related-to": "vnfc",
+ "related-link": "/aai/v11/network/vnfcs/vnfc/vfw",
+ "relationship-data": [
+ {
+ "relationship-key": "vnfc.vnfc-name",
+ "relationship-value": "vfw"
+ }
+ ]
+ },
+ {
+ "related-to": "vf-module",
+ "related-link": "/aai/v11/network/generic-vnfs/generic-vnf/17044ef4-e7f3-46a1-af03-e2aa562f23ac/vf-modules/vf-module/33f9e03d-2fbd-4e9c-8e73-ce6b12f0b3d2",
+ "relationship-data": [
+ {
+ "relationship-key": "generic-vnf.vnf-id",
+ "relationship-value": "17044ef4-e7f3-46a1-af03-e2aa562f23ac"
+ },
+ {
+ "relationship-key": "vf-module.vf-module-id",
+ "relationship-value": "33f9e03d-2fbd-4e9c-8e73-ce6b12f0b3d2"
+ }
+ ]
+ },
+ {
+ "related-to": "flavor",
+ "related-link": "/aai/v11/cloud-infrastructure/cloud-regions/cloud-region/CloudOwner/RegionOne/flavors/flavor/2",
+ "relationship-data": [
+ {
+ "relationship-key": "cloud-region.cloud-owner",
+ "relationship-value": "CloudOwner"
+ },
+ {
+ "relationship-key": "cloud-region.cloud-region-id",
+ "relationship-value": "RegionOne"
+ },
+ {
+ "relationship-key": "flavor.flavor-id",
+ "relationship-value": "2"
+ }
+ ],
+ "related-to-property": [
+ {
+ "property-key": "flavor.flavor-name",
+ "property-value": "m1.small"
+ }
+ ]
+ },
+ {
+ "related-to": "image",
+ "related-link": "/aai/v11/cloud-infrastructure/cloud-regions/cloud-region/CloudOwner/RegionOne/images/image/84be7136-301f-4f47-9585-3a2e0f9534af",
+ "relationship-data": [
+ {
+ "relationship-key": "cloud-region.cloud-owner",
+ "relationship-value": "CloudOwner"
+ },
+ {
+ "relationship-key": "cloud-region.cloud-region-id",
+ "relationship-value": "RegionOne"
+ },
+ {
+ "relationship-key": "image.image-id",
+ "relationship-value": "84be7136-301f-4f47-9585-3a2e0f9534af"
+ }
+ ],
+ "related-to-property": [
+ {
+ "property-key": "image.image-name",
+ "property-value": "unknown"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ {
+ "generic-vnf": {
+ "vnf-id": "7b202620-2936-4b0d-b09c-60b411f10f64",
+ "vnf-name": "vLoadBalancerMS-Vnf-0211-1",
+ "vnf-type": "vLoadBalancerMS/vLoadBalancerMS 0",
+ "prov-status": "ACTIVE",
+ "equipment-role": "vLB",
+ "orchestration-status": "Active",
+ "ipv4-oam-address": "10.0.150.1",
+ "in-maint": true,
+ "is-closed-loop-disabled": false,
+ "resource-version": "1552311656338",
+ "model-invariant-id": "724ab1cf-6120-49e8-b909-849963bed1d6",
+ "model-version-id": "9d5944d8-2267-4799-824a-0f824e9a978d",
+ "model-customization-id": "efcd576d-a05e-4798-bb68-79e7d9c80f4c",
+ "nf-type": "ONAP-LOADBALANCER",
+ "nf-function": "LOADBALANCER",
+ "nf-role": "vLB",
+ "nf-naming-code": "vlb",
+ "selflink": "restconf/config/GENERIC-RESOURCE-API:services/service/101b8fc1-1796-4db1-a4e7-fe39c6a51558/service-data/vnfs/vnf/7b202620-2936-4b0d-b09c-60b411f10f64/vnf-data/vnf-topology/",
+ "relationship-list": {
+ "relationship": [
+ {
+ "related-to": "service-instance",
+ "related-link": "/aai/v11/business/customers/customer/Demonstration/service-subscriptions/service-subscription/vLB/service-instances/service-instance/101b8fc1-1796-4db1-a4e7-fe39c6a51558",
+ "relationship-data": [
+ {
+ "relationship-key": "customer.global-customer-id",
+ "relationship-value": "Demonstration"
+ },
+ {
+ "relationship-key": "service-subscription.service-type",
+ "relationship-value": "vLB"
+ },
+ {
+ "relationship-key": "service-instance.service-instance-id",
+ "relationship-value": "101b8fc1-1796-4db1-a4e7-fe39c6a51558"
+ }
+ ],
+ "related-to-property": [
+ {
+ "property-key": "service-instance.service-instance-name",
+ "property-value": "vLoadBalancerMS-0211-1"
+ }
+ ]
+ },
+ {
+ "related-to": "platform",
+ "related-link": "/aai/v11/business/platforms/platform/Test-Platform",
+ "relationship-data": [
+ {
+ "relationship-key": "platform.platform-name",
+ "relationship-value": "Test-Platform"
+ }
+ ]
+ },
+ {
+ "related-to": "line-of-business",
+ "related-link": "/aai/v11/business/lines-of-business/line-of-business/Test-Business",
+ "relationship-data": [
+ {
+ "relationship-key": "line-of-business.line-of-business-name",
+ "relationship-value": "Test-Business"
+ }
+ ]
+ },
+ {
+ "related-to": "vserver",
+ "related-link": "/aai/v11/cloud-infrastructure/cloud-regions/cloud-region/CloudOwner/RegionOne/tenants/tenant/3f2aaef74ecb4b19b35e26d0849fe9a2/vservers/vserver/58ca8df0-17b8-4aa2-8766-9c6c1a12cec8",
+ "relationship-data": [
+ {
+ "relationship-key": "cloud-region.cloud-owner",
+ "relationship-value": "CloudOwner"
+ },
+ {
+ "relationship-key": "cloud-region.cloud-region-id",
+ "relationship-value": "RegionOne"
+ },
+ {
+ "relationship-key": "tenant.tenant-id",
+ "relationship-value": "3f2aaef74ecb4b19b35e26d0849fe9a2"
+ },
+ {
+ "relationship-key": "vserver.vserver-id",
+ "relationship-value": "58ca8df0-17b8-4aa2-8766-9c6c1a12cec8"
+ }
+ ],
+ "related-to-property": [
+ {
+ "property-key": "vserver.vserver-name",
+ "property-value": "vdns-ms-0211-1"
+ }
+ ]
+ },
+ {
+ "related-to": "vserver",
+ "related-link": "/aai/v11/cloud-infrastructure/cloud-regions/cloud-region/CloudOwner/RegionOne/tenants/tenant/3f2aaef74ecb4b19b35e26d0849fe9a2/vservers/vserver/6c3b3714-e36c-45af-9f16-7d3a73d99497",
+ "relationship-data": [
+ {
+ "relationship-key": "cloud-region.cloud-owner",
+ "relationship-value": "CloudOwner"
+ },
+ {
+ "relationship-key": "cloud-region.cloud-region-id",
+ "relationship-value": "RegionOne"
+ },
+ {
+ "relationship-key": "tenant.tenant-id",
+ "relationship-value": "3f2aaef74ecb4b19b35e26d0849fe9a2"
+ },
+ {
+ "relationship-key": "vserver.vserver-id",
+ "relationship-value": "6c3b3714-e36c-45af-9f16-7d3a73d99497"
+ }
+ ],
+ "related-to-property": [
+ {
+ "property-key": "vserver.vserver-name",
+ "property-value": "vlb-ms-0211-1"
+ }
+ ]
+ },
+ {
+ "related-to": "availability-zone",
+ "related-link": "/aai/v11/cloud-infrastructure/cloud-regions/cloud-region/CloudOwner/RegionOne/availability-zones/availability-zone/nova",
+ "relationship-data": [
+ {
+ "relationship-key": "cloud-region.cloud-owner",
+ "relationship-value": "CloudOwner"
+ },
+ {
+ "relationship-key": "cloud-region.cloud-region-id",
+ "relationship-value": "RegionOne"
+ },
+ {
+ "relationship-key": "availability-zone.availability-zone-name",
+ "relationship-value": "nova"
+ }
+ ]
+ }
+ ]
+ },
+ "vf-modules": {
+ "vf-module": [
+ {
+ "vf-module-id": "e46c6636-9ce5-4b77-bb1b-455ce9edc892",
+ "vf-module-name": "vLoadBalancerMS-0211-1",
+ "heat-stack-id": "vLoadBalancerMS-0211-1/73360253-2dfe-46f6-bcd6-8662a81238ea",
+ "orchestration-status": "Active",
+ "is-base-vf-module": true,
+ "resource-version": "1552311559802",
+ "model-invariant-id": "d263fc6d-cfce-4e20-8337-e06f48b474e6",
+ "model-version-id": "24c0aa10-3979-402c-ad98-20124751b551",
+ "model-customization-id": "65382eb1-db84-466c-b9d7-4e0f1ba7105f",
+ "selflink": "restconf/config/GENERIC-RESOURCE-API:services/service/101b8fc1-1796-4db1-a4e7-fe39c6a51558/service-data/vnfs/vnf/7b202620-2936-4b0d-b09c-60b411f10f64/vnf-data/vf-modules/vf-module/e46c6636-9ce5-4b77-bb1b-455ce9edc892/vf-module-data/vf-module-topology/",
+ "relationship-list": {
+ "relationship": [
+ {
+ "related-to": "vserver",
+ "related-link": "/aai/v11/cloud-infrastructure/cloud-regions/cloud-region/CloudOwner/RegionOne/tenants/tenant/3f2aaef74ecb4b19b35e26d0849fe9a2/vservers/vserver/58ca8df0-17b8-4aa2-8766-9c6c1a12cec8",
+ "relationship-data": [
+ {
+ "relationship-key": "cloud-region.cloud-owner",
+ "relationship-value": "CloudOwner"
+ },
+ {
+ "relationship-key": "cloud-region.cloud-region-id",
+ "relationship-value": "RegionOne"
+ },
+ {
+ "relationship-key": "tenant.tenant-id",
+ "relationship-value": "3f2aaef74ecb4b19b35e26d0849fe9a2"
+ },
+ {
+ "relationship-key": "vserver.vserver-id",
+ "relationship-value": "58ca8df0-17b8-4aa2-8766-9c6c1a12cec8"
+ }
+ ],
+ "related-to-property": [
+ {
+ "property-key": "vserver.vserver-name",
+ "property-value": "vdns-ms-0211-1"
+ }
+ ]
+ },
+ {
+ "related-to": "vserver",
+ "related-link": "/aai/v11/cloud-infrastructure/cloud-regions/cloud-region/CloudOwner/RegionOne/tenants/tenant/3f2aaef74ecb4b19b35e26d0849fe9a2/vservers/vserver/6c3b3714-e36c-45af-9f16-7d3a73d99497",
+ "relationship-data": [
+ {
+ "relationship-key": "cloud-region.cloud-owner",
+ "relationship-value": "CloudOwner"
+ },
+ {
+ "relationship-key": "cloud-region.cloud-region-id",
+ "relationship-value": "RegionOne"
+ },
+ {
+ "relationship-key": "tenant.tenant-id",
+ "relationship-value": "3f2aaef74ecb4b19b35e26d0849fe9a2"
+ },
+ {
+ "relationship-key": "vserver.vserver-id",
+ "relationship-value": "6c3b3714-e36c-45af-9f16-7d3a73d99497"
+ }
+ ],
+ "related-to-property": [
+ {
+ "property-key": "vserver.vserver-name",
+ "property-value": "vlb-ms-0211-1"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ },
+ {
+ "service-instance": {
+ "service-instance-id": "101b8fc1-1796-4db1-a4e7-fe39c6a51558",
+ "service-instance-name": "vLoadBalancerMS-0211-1",
+ "environment-context": "General_Revenue-Bearing",
+ "workload-context": "Production",
+ "model-invariant-id": "1008a768-1b67-407e-88c6-58c82b34ef42",
+ "model-version-id": "81f8c1cd-f664-4450-b3a4-be645613ab32",
+ "resource-version": "1552311350334",
+ "selflink": "restconf/config/GENERIC-RESOURCE-API:services/service/101b8fc1-1796-4db1-a4e7-fe39c6a51558/service-data/service-topology/",
+ "orchestration-status": "Active",
+ "relationship-list": {
+ "relationship": [
+ {
+ "related-to": "project",
+ "related-link": "/aai/v11/business/projects/project/Test-Project",
+ "relationship-data": [
+ {
+ "relationship-key": "project.project-name",
+ "relationship-value": "Test-Project"
+ }
+ ]
+ },
+ {
+ "related-to": "generic-vnf",
+ "related-link": "/aai/v11/network/generic-vnfs/generic-vnf/7b202620-2936-4b0d-b09c-60b411f10f64",
+ "relationship-data": [
+ {
+ "relationship-key": "generic-vnf.vnf-id",
+ "relationship-value": "7b202620-2936-4b0d-b09c-60b411f10f64"
+ }
+ ],
+ "related-to-property": [
+ {
+ "property-key": "generic-vnf.vnf-name",
+ "property-value": "vLoadBalancerMS-Vnf-0211-1"
+ }
+ ]
+ },
+ {
+ "related-to": "owning-entity",
+ "related-link": "/aai/v11/business/owning-entities/owning-entity/bb94a687-4f3b-40a3-914e-e98037d5ebd2",
+ "relationship-data": [
+ {
+ "relationship-key": "owning-entity.owning-entity-id",
+ "relationship-value": "bb94a687-4f3b-40a3-914e-e98037d5ebd2"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ {
+ "generic-vnf": {
+ "vnf-id": "17044ef4-e7f3-46a1-af03-e2aa562f23ac",
+ "vnf-name": "TestVM-Vnf-0201-1",
+ "vnf-type": "TestVM/TestVM 0",
+ "prov-status": "ACTIVE",
+ "equipment-role": "",
+ "orchestration-status": "Active",
+ "ipv4-oam-address": "10.0.70.1",
+ "in-maint": true,
+ "is-closed-loop-disabled": false,
+ "resource-version": "1549041636264",
+ "model-invariant-id": "6a4d7971-0778-4655-9eab-9d6031c7ad57",
+ "model-version-id": "fb6c673c-e5b6-4e0a-9baf-5e0089784de9",
+ "model-customization-id": "706a3100-dbe5-442e-86c3-c7b823abbec2",
+ "selflink": "restconf/config/GENERIC-RESOURCE-API:services/service/d41f8217-d464-4458-bf0a-fba33a0f1b31/service-data/vnfs/vnf/17044ef4-e7f3-46a1-af03-e2aa562f23ac/vnf-data/vnf-topology/",
+ "relationship-list": {
+ "relationship": [
+ {
+ "related-to": "service-instance",
+ "related-link": "/aai/v11/business/customers/customer/Demonstration/service-subscriptions/service-subscription/vFW/service-instances/service-instance/d41f8217-d464-4458-bf0a-fba33a0f1b31",
+ "relationship-data": [
+ {
+ "relationship-key": "customer.global-customer-id",
+ "relationship-value": "Demonstration"
+ },
+ {
+ "relationship-key": "service-subscription.service-type",
+ "relationship-value": "vFW"
+ },
+ {
+ "relationship-key": "service-instance.service-instance-id",
+ "relationship-value": "d41f8217-d464-4458-bf0a-fba33a0f1b31"
+ }
+ ],
+ "related-to-property": [
+ {
+ "property-key": "service-instance.service-instance-name",
+ "property-value": "TestVM-Service-0201-1"
+ }
+ ]
+ },
+ {
+ "related-to": "platform",
+ "related-link": "/aai/v11/business/platforms/platform/Test-Platform",
+ "relationship-data": [
+ {
+ "relationship-key": "platform.platform-name",
+ "relationship-value": "Test-Platform"
+ }
+ ]
+ },
+ {
+ "related-to": "line-of-business",
+ "related-link": "/aai/v11/business/lines-of-business/line-of-business/Test-Business",
+ "relationship-data": [
+ {
+ "relationship-key": "line-of-business.line-of-business-name",
+ "relationship-value": "Test-Business"
+ }
+ ]
+ },
+ {
+ "related-to": "vserver",
+ "related-link": "/aai/v11/cloud-infrastructure/cloud-regions/cloud-region/CloudOwner/RegionOne/tenants/tenant/3f2aaef74ecb4b19b35e26d0849fe9a2/vservers/vserver/e7f1db09-ff78-44fc-b256-69095c5556fb",
+ "relationship-data": [
+ {
+ "relationship-key": "cloud-region.cloud-owner",
+ "relationship-value": "CloudOwner"
+ },
+ {
+ "relationship-key": "cloud-region.cloud-region-id",
+ "relationship-value": "RegionOne"
+ },
+ {
+ "relationship-key": "tenant.tenant-id",
+ "relationship-value": "3f2aaef74ecb4b19b35e26d0849fe9a2"
+ },
+ {
+ "relationship-key": "vserver.vserver-id",
+ "relationship-value": "e7f1db09-ff78-44fc-b256-69095c5556fb"
+ }
+ ],
+ "related-to-property": [
+ {
+ "property-key": "vserver.vserver-name",
+ "property-value": "vfw-vm-0201-2"
+ }
+ ]
+ },
+ {
+ "related-to": "availability-zone",
+ "related-link": "/aai/v11/cloud-infrastructure/cloud-regions/cloud-region/CloudOwner/RegionTwo/availability-zones/availability-zone/zone-1",
+ "relationship-data": [
+ {
+ "relationship-key": "cloud-region.cloud-owner",
+ "relationship-value": "CloudOwner"
+ },
+ {
+ "relationship-key": "cloud-region.cloud-region-id",
+ "relationship-value": "RegionTwo"
+ },
+ {
+ "relationship-key": "availability-zone.availability-zone-name",
+ "relationship-value": "zone-1"
+ }
+ ]
+ }
+ ]
+ },
+ "vf-modules": {
+ "vf-module": [
+ {
+ "vf-module-id": "0afde97a-3e3f-4597-aec3-e5488c0f20b7",
+ "vf-module-name": "TestVM-0201-1",
+ "heat-stack-id": "TestVM-0201-1/aee4d7e5-b4a0-4261-b3cf-bb23348a3d99",
+ "orchestration-status": "Active",
+ "is-base-vf-module": true,
+ "resource-version": "1549039401119",
+ "model-invariant-id": "6af68fdb-6479-43e2-8989-938f06c994bd",
+ "model-version-id": "16d1834e-d834-431f-b064-98c469c6505d",
+ "model-customization-id": "29ffb122-22c8-48d2-b152-b52d9e81e910",
+ "selflink": "restconf/config/GENERIC-RESOURCE-API:services/service/d41f8217-d464-4458-bf0a-fba33a0f1b31/service-data/vnfs/vnf/17044ef4-e7f3-46a1-af03-e2aa562f23ac/vnf-data/vf-modules/vf-module/0afde97a-3e3f-4597-aec3-e5488c0f20b7/vf-module-data/vf-module-topology/"
+ },
+ {
+ "vf-module-id": "33f9e03d-2fbd-4e9c-8e73-ce6b12f0b3d2",
+ "vf-module-name": "TestVM-0201-2",
+ "heat-stack-id": "TestVM-0201-2/1b9db6b8-620b-46f1-935a-8a61c294a98b",
+ "orchestration-status": "Active",
+ "is-base-vf-module": true,
+ "resource-version": "1549041447373",
+ "model-invariant-id": "6af68fdb-6479-43e2-8989-938f06c994bd",
+ "model-version-id": "16d1834e-d834-431f-b064-98c469c6505d",
+ "model-customization-id": "29ffb122-22c8-48d2-b152-b52d9e81e910",
+ "selflink": "restconf/config/GENERIC-RESOURCE-API:services/service/d41f8217-d464-4458-bf0a-fba33a0f1b31/service-data/vnfs/vnf/17044ef4-e7f3-46a1-af03-e2aa562f23ac/vnf-data/vf-modules/vf-module/33f9e03d-2fbd-4e9c-8e73-ce6b12f0b3d2/vf-module-data/vf-module-topology/",
+ "relationship-list": {
+ "relationship": [
+ {
+ "related-to": "vserver",
+ "related-link": "/aai/v11/cloud-infrastructure/cloud-regions/cloud-region/CloudOwner/RegionOne/tenants/tenant/3f2aaef74ecb4b19b35e26d0849fe9a2/vservers/vserver/e7f1db09-ff78-44fc-b256-69095c5556fb",
+ "relationship-data": [
+ {
+ "relationship-key": "cloud-region.cloud-owner",
+ "relationship-value": "CloudOwner"
+ },
+ {
+ "relationship-key": "cloud-region.cloud-region-id",
+ "relationship-value": "RegionOne"
+ },
+ {
+ "relationship-key": "tenant.tenant-id",
+ "relationship-value": "3f2aaef74ecb4b19b35e26d0849fe9a2"
+ },
+ {
+ "relationship-key": "vserver.vserver-id",
+ "relationship-value": "e7f1db09-ff78-44fc-b256-69095c5556fb"
+ }
+ ],
+ "related-to-property": [
+ {
+ "property-key": "vserver.vserver-name",
+ "property-value": "vfw-vm-0201-2"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ },
+ {
+ "vf-module": {
+ "vf-module-id": "0afde97a-3e3f-4597-aec3-e5488c0f20b7",
+ "vf-module-name": "TestVM-0201-1",
+ "heat-stack-id": "TestVM-0201-1/aee4d7e5-b4a0-4261-b3cf-bb23348a3d99",
+ "orchestration-status": "Active",
+ "is-base-vf-module": true,
+ "resource-version": "1549039401119",
+ "model-invariant-id": "6af68fdb-6479-43e2-8989-938f06c994bd",
+ "model-version-id": "16d1834e-d834-431f-b064-98c469c6505d",
+ "model-customization-id": "29ffb122-22c8-48d2-b152-b52d9e81e910",
+ "selflink": "restconf/config/GENERIC-RESOURCE-API:services/service/d41f8217-d464-4458-bf0a-fba33a0f1b31/service-data/vnfs/vnf/17044ef4-e7f3-46a1-af03-e2aa562f23ac/vnf-data/vf-modules/vf-module/0afde97a-3e3f-4597-aec3-e5488c0f20b7/vf-module-data/vf-module-topology/"
+ }
+ },
+ {
+ "vf-module": {
+ "vf-module-id": "33f9e03d-2fbd-4e9c-8e73-ce6b12f0b3d2",
+ "vf-module-name": "TestVM-0201-2",
+ "heat-stack-id": "TestVM-0201-2/1b9db6b8-620b-46f1-935a-8a61c294a98b",
+ "orchestration-status": "Active",
+ "is-base-vf-module": true,
+ "resource-version": "1549041447373",
+ "model-invariant-id": "6af68fdb-6479-43e2-8989-938f06c994bd",
+ "model-version-id": "16d1834e-d834-431f-b064-98c469c6505d",
+ "model-customization-id": "29ffb122-22c8-48d2-b152-b52d9e81e910",
+ "selflink": "restconf/config/GENERIC-RESOURCE-API:services/service/d41f8217-d464-4458-bf0a-fba33a0f1b31/service-data/vnfs/vnf/17044ef4-e7f3-46a1-af03-e2aa562f23ac/vnf-data/vf-modules/vf-module/33f9e03d-2fbd-4e9c-8e73-ce6b12f0b3d2/vf-module-data/vf-module-topology/",
+ "relationship-list": {
+ "relationship": [
+ {
+ "related-to": "vserver",
+ "related-link": "/aai/v11/cloud-infrastructure/cloud-regions/cloud-region/CloudOwner/RegionOne/tenants/tenant/3f2aaef74ecb4b19b35e26d0849fe9a2/vservers/vserver/e7f1db09-ff78-44fc-b256-69095c5556fb",
+ "relationship-data": [
+ {
+ "relationship-key": "cloud-region.cloud-owner",
+ "relationship-value": "CloudOwner"
+ },
+ {
+ "relationship-key": "cloud-region.cloud-region-id",
+ "relationship-value": "RegionOne"
+ },
+ {
+ "relationship-key": "tenant.tenant-id",
+ "relationship-value": "3f2aaef74ecb4b19b35e26d0849fe9a2"
+ },
+ {
+ "relationship-key": "vserver.vserver-id",
+ "relationship-value": "e7f1db09-ff78-44fc-b256-69095c5556fb"
+ }
+ ],
+ "related-to-property": [
+ {
+ "property-key": "vserver.vserver-name",
+ "property-value": "vfw-vm-0201-2"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ {
+ "tenant": {
+ "tenant-id": "tenant1-16197-as988q",
+ "tenant-name": "tenant-name-16197-as988q",
+ "resource-version": "1550769793637",
+ "vservers": {
+ "vserver": [
+ {
+ "vserver-id": "vserver1-16197-as988q",
+ "vserver-name": "vserverName",
+ "vserver-name2": "vserverTE-name2-as988q",
+ "prov-status": "ACTIVE",
+ "vserver-selflink": "TRINITY vserverLink",
+ "in-maint": false,
+ "is-closed-loop-disabled": false,
+ "resource-version": "1550769794551",
+ "relationship-list": {
+ "relationship": [
+ {
+ "related-to": "generic-vnf",
+ "relationship-label": "tosca.relationships.HostedOn",
+ "related-link": "/aai/v16/network/generic-vnfs/generic-vnf/VNF1-16197-as988q",
+ "relationship-data": [
+ {
+ "relationship-key": "generic-vnf.vnf-id",
+ "relationship-value": "VNF1-16197-as988q"
+ }
+ ],
+ "related-to-property": [
+ {
+ "property-key": "generic-vnf.vnf-name",
+ "property-value": "vnf1Name"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ },
+ {
+ "cloud-region": {
+ "cloud-owner": "co-16197-01-as988q",
+ "cloud-region-id": "cr-16197-01-as988q",
+ "resource-version": "1550769792672",
+ "orchestration-disabled": false,
+ "in-maint": false,
+ "tenants": {
+ "tenant": [
+ {
+ "tenant-id": "tenant1-16197-as988q",
+ "tenant-name": "tenant-name-16197-as988q",
+ "resource-version": "1550769793637"
+ }
+ ]
+ }
+ }
+ }
+ ]
+}
diff --git a/models-interactions/model-actors/actor.so/src/test/resources/org/onap/policy/controlloop/actor/so/aai/AaiCqResponseMissing.json b/models-interactions/model-actors/actor.so/src/test/resources/org/onap/policy/controlloop/actor/so/aai/AaiCqResponseMissing.json
new file mode 100644
index 000000000..29f1cdd8f
--- /dev/null
+++ b/models-interactions/model-actors/actor.so/src/test/resources/org/onap/policy/controlloop/actor/so/aai/AaiCqResponseMissing.json
@@ -0,0 +1,4 @@
+{
+ "results": [
+ ]
+}