From 971a95aab8f15a140f407d3a3b47fd783fd51ad1 Mon Sep 17 00:00:00 2001 From: Pamela Dragosh Date: Wed, 26 Aug 2020 13:50:57 -0400 Subject: Add guard filter properties to controller Adding new properties to guard Decision call. Issue-ID: POLICY-2590 Change-Id: Ie4a37990e062c76ac4d6dd1b904ad354736fd27a Signed-off-by: Pamela Dragosh Signed-off-by: Jim Hahn Signed-off-by: Pamela Dragosh --- .../apps/controller/usecases/step/GuardStep2.java | 82 +++++++++++++ .../apps/controller/usecases/step/Step2.java | 6 + .../controller/usecases/step/GuardStep2Test.java | 129 ++++++++++++++++++++- .../src/main/resources/vfw/vfw.onset.json | 2 +- 4 files changed, 212 insertions(+), 7 deletions(-) diff --git a/controlloop/common/controller-usecases/src/main/java/org/onap/policy/drools/apps/controller/usecases/step/GuardStep2.java b/controlloop/common/controller-usecases/src/main/java/org/onap/policy/drools/apps/controller/usecases/step/GuardStep2.java index b7247ce69..abc2bcb46 100644 --- a/controlloop/common/controller-usecases/src/main/java/org/onap/policy/drools/apps/controller/usecases/step/GuardStep2.java +++ b/controlloop/common/controller-usecases/src/main/java/org/onap/policy/drools/apps/controller/usecases/step/GuardStep2.java @@ -24,11 +24,18 @@ import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import org.onap.aai.domain.yang.GenericVnf; +import org.onap.aai.domain.yang.RelatedToProperty; +import org.onap.aai.domain.yang.Relationship; +import org.onap.aai.domain.yang.RelationshipData; +import org.onap.policy.aai.AaiCqResponse; import org.onap.policy.controlloop.actor.guard.DecisionOperation; import org.onap.policy.controlloop.actor.guard.GuardActor; import org.onap.policy.controlloop.actor.so.VfModuleCreate; import org.onap.policy.controlloop.actorserviceprovider.Operation; import org.onap.policy.controlloop.actorserviceprovider.OperationProperties; +import org.onap.policy.controlloop.actorserviceprovider.TargetType; +import org.onap.policy.drools.apps.controller.usecases.UsecasesConstants; /** * Wrapper for a Guard operation. Note: this makes a clone of the operation parameters, @@ -41,6 +48,12 @@ import org.onap.policy.controlloop.actorserviceprovider.OperationProperties; public class GuardStep2 extends Step2 { public static final String PAYLOAD_KEY_TARGET_ENTITY = "target"; public static final String PAYLOAD_KEY_VF_COUNT = "vfCount"; + public static final String PAYLOAD_KEY_VNF_NAME = "generic-vnf.vnf-name"; + public static final String PAYLOAD_KEY_VNF_ID = "generic-vnf.vnf-id"; + public static final String PAYLOAD_KEY_VNF_TYPE = "generic-vnf.vnf-type"; + public static final String PAYLOAD_KEY_NF_NAMING_CODE = "generic-vnf.nf-naming-code"; + public static final String PAYLOAD_KEY_VSERVER_ID = "vserver.vserver-id"; + public static final String PAYLOAD_KEY_CLOUD_REGION_ID = "cloud-region.cloud-region-id"; private final Operation policyOper; @@ -85,6 +98,12 @@ public class GuardStep2 extends Step2 { names.add(OperationProperties.DATA_VF_COUNT); } + // Only get filter properties if the vserver-name exists, which is needed to call cq + if (event.getAai().get("vserver.vserver-name") != null) { + names.add(UsecasesConstants.AAI_DEFAULT_GENERIC_VNF); + names.add(OperationProperties.AAI_DEFAULT_CLOUD_REGION); + } + return names; } @@ -112,4 +131,67 @@ public class GuardStep2 extends Step2 { params.getPayload().put(PAYLOAD_KEY_VF_COUNT, count); } + + @Override + protected void loadCloudRegion(String propName) { + // PNF does not support guard filters + if (TargetType.PNF.equals(params.getTargetType())) { + return; + } + + params.getPayload().put(PAYLOAD_KEY_CLOUD_REGION_ID, getCloudRegion().getCloudRegionId()); + } + + @Override + protected void loadDefaultGenericVnf(String propName) { + // PNF does not support guard filters + if (TargetType.PNF.equals(params.getTargetType())) { + return; + } + + // add in properties needed for filters + String targetEntity = getTargetEntity(); + params.getPayload().put(PAYLOAD_KEY_VNF_ID, targetEntity); + + AaiCqResponse cq = this.getCustomQueryData(); + GenericVnf vnf = cq.getGenericVnfByVnfId(targetEntity); + if (vnf == null) { + return; + } + params.getPayload().put(PAYLOAD_KEY_VNF_NAME, vnf.getVnfName()); + params.getPayload().put(PAYLOAD_KEY_VNF_TYPE, vnf.getVnfType()); + params.getPayload().put(PAYLOAD_KEY_NF_NAMING_CODE, vnf.getNfNamingCode()); + + String vserverName = getEnrichment(OperationProperties.ENRICHMENT_VSERVER_NAME); + + params.getPayload().put(PAYLOAD_KEY_VSERVER_ID, findServerId(vnf, vserverName)); + } + + private String findServerId(GenericVnf vnf, String vserverName) { + for (Relationship relationship : vnf.getRelationshipList().getRelationship()) { + if (!"vserver".equals(relationship.getRelatedTo())) { + continue; + } + String vserverId = findServerId(relationship, vserverName); + if (vserverId != null) { + return vserverId; + } + } + return null; + } + + private String findServerId(Relationship relationship, String vserverName) { + for (RelatedToProperty to : relationship.getRelatedToProperty()) { + if ("vserver.vserver-name".equals(to.getPropertyKey()) && vserverName.equals(to.getPropertyValue())) { + // Found the right relationship server-name, now find the server-id + for (RelationshipData data : relationship.getRelationshipData()) { + if (PAYLOAD_KEY_VSERVER_ID.equals(data.getRelationshipKey())) { + return data.getRelationshipValue(); + } + } + } + } + return null; + } + } diff --git a/controlloop/common/controller-usecases/src/main/java/org/onap/policy/drools/apps/controller/usecases/step/Step2.java b/controlloop/common/controller-usecases/src/main/java/org/onap/policy/drools/apps/controller/usecases/step/Step2.java index 5d80ea5f4..ca7b63f69 100644 --- a/controlloop/common/controller-usecases/src/main/java/org/onap/policy/drools/apps/controller/usecases/step/Step2.java +++ b/controlloop/common/controller-usecases/src/main/java/org/onap/policy/drools/apps/controller/usecases/step/Step2.java @@ -36,6 +36,7 @@ import org.onap.aai.domain.yang.GenericVnf; import org.onap.aai.domain.yang.ModelVer; import org.onap.aai.domain.yang.ServiceInstance; import org.onap.aai.domain.yang.Tenant; +import org.onap.aai.domain.yang.Vserver; import org.onap.policy.aai.AaiCqResponse; import org.onap.policy.common.utils.coder.StandardCoderObject; import org.onap.policy.controlloop.VirtualControlLoopEvent; @@ -318,6 +319,11 @@ public class Step2 extends Step { return aaicq.getModelVerByVersionId(service.getModelVersionId()); } + protected Vserver getVServer() { + AaiCqResponse aaicq = getCustomQueryData(); + return aaicq.getVserver(); + } + /** * The default method assumes there is only one target entity and that it's stored * within the step's context. diff --git a/controlloop/common/controller-usecases/src/test/java/org/onap/policy/drools/apps/controller/usecases/step/GuardStep2Test.java b/controlloop/common/controller-usecases/src/test/java/org/onap/policy/drools/apps/controller/usecases/step/GuardStep2Test.java index 6514b4f95..131e5d3c8 100644 --- a/controlloop/common/controller-usecases/src/test/java/org/onap/policy/drools/apps/controller/usecases/step/GuardStep2Test.java +++ b/controlloop/common/controller-usecases/src/test/java/org/onap/policy/drools/apps/controller/usecases/step/GuardStep2Test.java @@ -27,6 +27,7 @@ import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.when; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; @@ -34,21 +35,40 @@ import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.onap.aai.domain.yang.CloudRegion; +import org.onap.aai.domain.yang.GenericVnf; +import org.onap.aai.domain.yang.RelatedToProperty; +import org.onap.aai.domain.yang.Relationship; +import org.onap.aai.domain.yang.RelationshipData; +import org.onap.aai.domain.yang.RelationshipList; +import org.onap.aai.domain.yang.Vserver; +import org.onap.policy.aai.AaiCqResponse; import org.onap.policy.controlloop.VirtualControlLoopEvent; import org.onap.policy.controlloop.actor.guard.DecisionOperation; import org.onap.policy.controlloop.actor.guard.GuardActor; import org.onap.policy.controlloop.actor.so.VfModuleCreate; import org.onap.policy.controlloop.actorserviceprovider.Operation; import org.onap.policy.controlloop.actorserviceprovider.OperationProperties; +import org.onap.policy.controlloop.actorserviceprovider.TargetType; import org.onap.policy.controlloop.actorserviceprovider.controlloop.ControlLoopEventContext; import org.onap.policy.controlloop.actorserviceprovider.parameters.ControlLoopOperationParams; import org.onap.policy.controlloop.eventmanager.StepContext; +import org.onap.policy.drools.apps.controller.usecases.UsecasesConstants; public class GuardStep2Test { + private static final String SOME_OTHER_VALUE = "some-other-value"; + private static final String SOME_OTHER_KEY = "some-other-key"; private static final String CL_NAME = "my-closed-loop"; private static final String MASTER_ACTOR = "master-actor"; private static final String MASTER_OPERATION = "master-operation"; private static final String MY_TARGET = "my-target"; + private static final String MY_NAME = "my-name"; + private static final String MY_TYPE = "my-type"; + private static final String MY_CODE = "my-code"; + private static final String MY_SERVER = "my-server"; + private static final String MY_SERVER2 = "my-server-2"; + private static final String MY_SERVERNAME = "my-server-name"; + private static final String MY_REGION = "my-region"; private static final UUID REQ_ID = UUID.randomUUID(); private static final int VF_COUNT = 10; @@ -60,6 +80,16 @@ public class GuardStep2Test { private VirtualControlLoopEvent event; @Mock private Operation policyOper; + @Mock + private AaiCqResponse customQuery; + @Mock + private GenericVnf genericVnf; + @Mock + private CloudRegion cloudRegion; + @Mock Vserver theVserver; + + TargetType target; + Map aai = new HashMap<>(); private ControlLoopOperationParams params; private Step2 master; @@ -72,17 +102,82 @@ public class GuardStep2Test { public void setUp() { MockitoAnnotations.initMocks(this); + aai.put("vserver.vserver-name", MY_SERVERNAME); when(event.getRequestId()).thenReturn(REQ_ID); + when(event.getAai()).thenReturn(aai); when(context.getEvent()).thenReturn(event); + when(genericVnf.getVnfId()).thenReturn(MY_TARGET); + when(genericVnf.getVnfName()).thenReturn(MY_NAME); + when(genericVnf.getVnfType()).thenReturn(MY_TYPE); + when(genericVnf.getNfNamingCode()).thenReturn(MY_CODE); + + RelationshipList relList = new RelationshipList(); + when(genericVnf.getRelationshipList()).thenReturn(relList); + + relList.getRelationship().add(new Relationship()); + + Relationship relationship = new Relationship(); + relList.getRelationship().add(relationship); + relationship.setRelatedTo("vserver"); + + relationship.getRelatedToProperty().add(new RelatedToProperty()); + + // property key mismatch + RelatedToProperty relProp = new RelatedToProperty(); + relationship.getRelatedToProperty().add(relProp); + relProp.setPropertyKey(SOME_OTHER_KEY); + relProp.setPropertyValue(MY_NAME); + + // property value mismatch + relProp = new RelatedToProperty(); + relationship.getRelatedToProperty().add(relProp); + relProp.setPropertyKey("vserver.vserver-name"); + relProp.setPropertyValue(SOME_OTHER_VALUE); + + // matching property + relProp = new RelatedToProperty(); + relationship.getRelatedToProperty().add(relProp); + relProp.setPropertyKey("vserver.vserver-name"); + relProp.setPropertyValue(MY_SERVERNAME); + + // data key mismatch + RelationshipData relData = new RelationshipData(); + relationship.getRelationshipData().add(relData); + relData.setRelationshipKey(SOME_OTHER_KEY); + relData.setRelationshipValue(SOME_OTHER_VALUE); + + // matching data + relData = new RelationshipData(); + relationship.getRelationshipData().add(relData); + relData.setRelationshipKey(GuardStep2.PAYLOAD_KEY_VSERVER_ID); + relData.setRelationshipValue(MY_SERVER2); + + when(customQuery.getGenericVnfByVnfId(MY_TARGET)).thenReturn(genericVnf); + + when(theVserver.getVserverId()).thenReturn(MY_SERVER); + when(customQuery.getVserver()).thenReturn(theVserver); + + when(cloudRegion.getCloudRegionId()).thenReturn(MY_REGION); + when(customQuery.getDefaultCloudRegion()).thenReturn(cloudRegion); + when(stepContext.getProperty(OperationProperties.AAI_TARGET_ENTITY)).thenReturn(MY_TARGET); + when(stepContext.getProperty(AaiCqResponse.CONTEXT_KEY)).thenReturn(customQuery); + //when(stepContext.getProperty(VSERVER_VSERVER_NAME)).thenReturn() + when(stepContext.contains(OperationProperties.DATA_VF_COUNT)).thenReturn(true); when(stepContext.getProperty(OperationProperties.DATA_VF_COUNT)).thenReturn(VF_COUNT); - - params = ControlLoopOperationParams.builder().actor(MASTER_ACTOR).operation(MASTER_OPERATION) - .targetEntity(MY_TARGET).context(context).build(); + // @formatter:off + params = ControlLoopOperationParams.builder() + .actor(MASTER_ACTOR) + .operation(MASTER_OPERATION) + .targetEntity(MY_TARGET) + .context(context) + .targetType(target) + .build(); + // @formatter:on master = new Step2(stepContext, params, event) { @Override @@ -129,11 +224,16 @@ public class GuardStep2Test { public void testGetPropertyNames() { // unmatching property names when(policyOper.getPropertyNames()).thenReturn(List.of("propA", "propB")); - assertThat(step.getPropertyNames()).isEmpty(); + assertThat(step.getPropertyNames()) + .containsAll(List.of(UsecasesConstants.AAI_DEFAULT_GENERIC_VNF, + OperationProperties.AAI_DEFAULT_CLOUD_REGION)); // matching property names - when(policyOper.getPropertyNames()).thenReturn(List.of("propA", OperationProperties.DATA_VF_COUNT, "propB")); - assertThat(step.getPropertyNames()).isEqualTo(List.of(OperationProperties.DATA_VF_COUNT)); + when(policyOper.getPropertyNames()) + .thenReturn(List.of("propA", OperationProperties.DATA_VF_COUNT, "propB")); + assertThat(step.getPropertyNames()).containsAll(List.of(OperationProperties.DATA_VF_COUNT, + UsecasesConstants.AAI_DEFAULT_GENERIC_VNF, + OperationProperties.AAI_DEFAULT_CLOUD_REGION)); } @Test @@ -142,6 +242,23 @@ public class GuardStep2Test { assertThat(step.getParams().getPayload()).containsEntry(GuardStep2.PAYLOAD_KEY_TARGET_ENTITY, MY_TARGET); } + @Test + public void testLoadDefaultGenericVnf() { + step.loadDefaultGenericVnf(OperationProperties.AAI_VNF); + assertThat(step.getParams().getPayload()) + .containsEntry(GuardStep2.PAYLOAD_KEY_VNF_ID, MY_TARGET) + .containsEntry(GuardStep2.PAYLOAD_KEY_VNF_NAME, MY_NAME) + .containsEntry(GuardStep2.PAYLOAD_KEY_VNF_TYPE, MY_TYPE) + .containsEntry(GuardStep2.PAYLOAD_KEY_NF_NAMING_CODE, MY_CODE) + .containsEntry(GuardStep2.PAYLOAD_KEY_VSERVER_ID, MY_SERVER2); + } + + @Test + public void testLoadCloudRegion() { + step.loadCloudRegion(OperationProperties.AAI_DEFAULT_CLOUD_REGION); + assertThat(step.getParams().getPayload()).containsEntry(GuardStep2.PAYLOAD_KEY_CLOUD_REGION_ID, MY_REGION); + } + /** * Tests loadVfCount() when the policy operation is NOT "VF Module Create". */ diff --git a/controlloop/common/rules-test/src/main/resources/vfw/vfw.onset.json b/controlloop/common/rules-test/src/main/resources/vfw/vfw.onset.json index 7782867a1..fb727085c 100644 --- a/controlloop/common/rules-test/src/main/resources/vfw/vfw.onset.json +++ b/controlloop/common/rules-test/src/main/resources/vfw/vfw.onset.json @@ -10,7 +10,7 @@ "vserver.is-closed-loop-disabled": "false", "vserver.prov-status": "ACTIVE", "generic-vnf.vnf-name": "fw0002vm002fw002", - "vserver.vserver-name": "OzVServer" + "vserver.vserver-name": "Ete_vFWCLvFWSNK_7ba1fbde_0" }, "from": "DCAE", "version": "1.0.2" -- cgit 1.2.3-korg