From 73e3ea2f9183fc7ed6ba8c0f221e41a804fbe2c7 Mon Sep 17 00:00:00 2001 From: Rashmi Pujar Date: Tue, 29 Oct 2019 16:13:05 -0400 Subject: PNF support changes in policy/models AAI Enrichment method for PNF target-type and unit tests. Addition of a hashmap field to ControlLoopEvent class to hold event specific parameters. Update CDS actor to include additional event parameters Issue-ID: POLICY-1187 Signed-off-by: Rashmi Pujar Change-Id: Ie0ceb320943531de6e6bc8675844b29a358dfb7e --- .../actor/cds/CdsActorServiceProvider.java | 5 ++ .../actor/cds/request/CdsActionRequest.java | 11 ++-- .../actor/cds/request/CdsActionRequestTest.java | 4 ++ .../main/java/org/onap/policy/aai/AaiManager.java | 59 ++++++++++++++++++---- .../java/org/onap/policy/aai/AaiManagerTest.java | 43 ++++++++++------ .../onap/policy/controlloop/ControlLoopEvent.java | 31 +++--------- .../policy/controlloop/ControlLoopTargetType.java | 1 + .../controlloop/ControlLoopTargetTypeTest.java | 1 + 8 files changed, 102 insertions(+), 53 deletions(-) diff --git a/models-interactions/model-actors/actor.cds/src/main/java/org/onap/policy/controlloop/actor/cds/CdsActorServiceProvider.java b/models-interactions/model-actors/actor.cds/src/main/java/org/onap/policy/controlloop/actor/cds/CdsActorServiceProvider.java index 65cc03931..df13ba306 100644 --- a/models-interactions/model-actors/actor.cds/src/main/java/org/onap/policy/controlloop/actor/cds/CdsActorServiceProvider.java +++ b/models-interactions/model-actors/actor.cds/src/main/java/org/onap/policy/controlloop/actor/cds/CdsActorServiceProvider.java @@ -130,6 +130,11 @@ public class CdsActorServiceProvider implements Actor { // E.g. For vFW usecase El-Alto inject service-instance-id, generic-vnf-id as needed by CDS. request.setAaiProperties(aaiParams); + // Inject any additional event parameters that may be present in the onset event + if (onset.getAdditionalEventParams() != null) { + request.setAdditionalEventParams(onset.getAdditionalEventParams()); + } + Builder struct = Struct.newBuilder(); try { String requestStr = request.generateCdsPayload(); diff --git a/models-interactions/model-actors/actor.cds/src/main/java/org/onap/policy/controlloop/actor/cds/request/CdsActionRequest.java b/models-interactions/model-actors/actor.cds/src/main/java/org/onap/policy/controlloop/actor/cds/request/CdsActionRequest.java index 38ab2bdc7..4193db59f 100644 --- a/models-interactions/model-actors/actor.cds/src/main/java/org/onap/policy/controlloop/actor/cds/request/CdsActionRequest.java +++ b/models-interactions/model-actors/actor.cds/src/main/java/org/onap/policy/controlloop/actor/cds/request/CdsActionRequest.java @@ -38,16 +38,18 @@ public class CdsActionRequest implements Serializable { private String resolutionKey; private Map aaiProperties; private Map policyPayload; + private Map additionalEventParams; /** * Generate the CDS gRPC request payload from the action-name (aka operational policy recipe). * The CDS gRPC request payload generation follows the below pattern: * { * "{@link CdsActionRequest#getActionName()}-request": { - * "resolution-key": "{@link CdsActionRequest#getResolutionKey()} ()}", + * "resolution-key": "{@link CdsActionRequest#getResolutionKey()}", * "{@link CdsActionRequest#getActionName()}-properties": { - * "{@link CdsActionRequest#getAaiProperties()} ()}", - * "{@link CdsActionRequest#getPolicyPayload()} ()}" + * "{@link CdsActionRequest#getAaiProperties()}", + * "{@link CdsActionRequest#getPolicyPayload()}", + * "{@link CdsActionRequest#getAdditionalEventParams()}" * } * } * } @@ -59,6 +61,9 @@ public class CdsActionRequest implements Serializable { Map cdsActionPropsMap = new LinkedHashMap<>(); cdsActionPropsMap.putAll(aaiProperties); cdsActionPropsMap.putAll(policyPayload); + if (additionalEventParams != null) { + cdsActionPropsMap.putAll(additionalEventParams); + } // 2. Build the enclosing CDS action request properties object to contain (1) and the resolution-key Map cdsActionRequestMap = new LinkedHashMap<>(); diff --git a/models-interactions/model-actors/actor.cds/src/test/java/org/onap/policy/controlloop/actor/cds/request/CdsActionRequestTest.java b/models-interactions/model-actors/actor.cds/src/test/java/org/onap/policy/controlloop/actor/cds/request/CdsActionRequestTest.java index 3f28bada4..e34fa33ab 100644 --- a/models-interactions/model-actors/actor.cds/src/test/java/org/onap/policy/controlloop/actor/cds/request/CdsActionRequestTest.java +++ b/models-interactions/model-actors/actor.cds/src/test/java/org/onap/policy/controlloop/actor/cds/request/CdsActionRequestTest.java @@ -43,6 +43,10 @@ public class CdsActionRequestTest { ImmutableMap.of("service-instance.service-instance-id", "1234", "generic-vnf.vnf-id", "5678"); req.setAaiProperties(aaiParams); + Map eventParams = + ImmutableMap.of("event-param-1", "1234", "event-param-2", "5678"); + req.setAdditionalEventParams(eventParams); + // Act String result = req.generateCdsPayload(); diff --git a/models-interactions/model-impl/aai/src/main/java/org/onap/policy/aai/AaiManager.java b/models-interactions/model-impl/aai/src/main/java/org/onap/policy/aai/AaiManager.java index 20998ae0c..d95068b2b 100644 --- a/models-interactions/model-impl/aai/src/main/java/org/onap/policy/aai/AaiManager.java +++ b/models-interactions/model-impl/aai/src/main/java/org/onap/policy/aai/AaiManager.java @@ -23,15 +23,21 @@ package org.onap.policy.aai; import com.google.gson.JsonSyntaxException; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; import java.util.UUID; +import java.util.stream.Collectors; import org.json.JSONArray; import org.json.JSONObject; import org.onap.policy.aai.util.Serialization; import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; import org.onap.policy.common.endpoints.utils.NetLoggerUtil; import org.onap.policy.common.endpoints.utils.NetLoggerUtil.EventType; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; import org.onap.policy.rest.RestManager; import org.onap.policy.rest.RestManager.Pair; import org.slf4j.Logger; @@ -47,16 +53,19 @@ public final class AaiManager { private static final String APPLICATION_JSON = "application/json"; + private static final StandardCoder CODER = new StandardCoder(); + /** The rest manager. */ // The REST manager used for processing REST calls for this AAI manager private final RestManager restManager; - /** custom query URLs. */ + /** custom query and other AAI resource URLs. */ private static final String CQ_URL = "/aai/v16/query?format=resource"; private static final String TENANT_URL = "/aai/v16/search/nodes-query?search-node-type=vserver&filter=vserver-name:EQUALS:"; private static final String PREFIX = "/aai/v16"; - + private static final String PNF_URL = PREFIX + "/network/pnfs/pnf/"; + private static final String AAI_DEPTH_SUFFIX = "?depth=0"; /** * Constructor, create the AAI manager with the specified REST manager. @@ -96,7 +105,6 @@ public final class AaiManager { } } - /** * This method is used to get the information for custom query. * @@ -116,8 +124,6 @@ public final class AaiManager { return createCustomQueryPayload(getResponse); } - - /** * Calls Aai and returns a custom query response for a vserver. * @@ -161,8 +167,6 @@ public final class AaiManager { return null; } - - /** * Returns the string response of a get query. * @@ -213,7 +217,6 @@ public final class AaiManager { return null; } - /** * Post a query to A&AI. * @@ -303,12 +306,12 @@ public final class AaiManager { * Perform a GET query for a particular entity towards A&AI. * * @param the generic type for the response - * @param urlGet the A&AI URL + * @param url the A&AI URL * @param username the user name for authentication * @param password the password for authentication * @param requestId the UUID of the request * @param key the name of the VNF - * @param classOfT the class of the response to return + * @param classOfResponse the class of the response to return * @return the response for the virtual server from A&AI */ private T getQuery(final String url, final String username, final String password, final UUID requestId, @@ -367,7 +370,6 @@ public final class AaiManager { return headers; } - /** * This method uses Google's GSON to create a response object from a JSON string. * @@ -389,4 +391,39 @@ public final class AaiManager { return null; } } + + /** + * Perform a GET request for a particular PNF by PNF ID towards A&AI. + * + * @param url the A&AI URL + * @param username the user name for authentication + * @param password the password for authentication + * @param requestId the UUID of the request + * @param pnfName the AAI unique identifier for PNF object + * @return HashMap of PNF properties + */ + public Map getPnf(String url, String username, String password, UUID requestId, String pnfName) { + String urlGet; + try { + urlGet = url + PNF_URL; + pnfName = URLEncoder.encode(pnfName, StandardCharsets.UTF_8.toString()) + AAI_DEPTH_SUFFIX; + } catch (UnsupportedEncodingException e) { + logger.error("Failed to encode the pnfName: {} using UTF-8 encoding. {}", pnfName, e); + return null; + } + String responseGet = getStringQuery(urlGet, username, password, requestId, pnfName); + if (responseGet == null) { + logger.error("Null response from AAI for the url: {}.", urlGet); + return null; + } + try { + Map pnfParams = CODER.decode(responseGet, HashMap.class); + // Map to AAI node.attribute notation + return pnfParams.entrySet().stream() + .collect(Collectors.toMap(e -> "pnf." + e.getKey(), Map.Entry::getValue)); + } catch (CoderException e) { + logger.error("Failed to fetch PNF from AAI"); + return null; + } + } } diff --git a/models-interactions/model-impl/aai/src/test/java/org/onap/policy/aai/AaiManagerTest.java b/models-interactions/model-impl/aai/src/test/java/org/onap/policy/aai/AaiManagerTest.java index 9a8d7d260..ff86577b9 100644 --- a/models-interactions/model-impl/aai/src/test/java/org/onap/policy/aai/AaiManagerTest.java +++ b/models-interactions/model-impl/aai/src/test/java/org/onap/policy/aai/AaiManagerTest.java @@ -21,10 +21,12 @@ package org.onap.policy.aai; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.mockito.ArgumentMatchers.anyMap; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.contains; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.ArgumentMatchers.startsWith; @@ -34,7 +36,6 @@ import static org.mockito.Mockito.when; import java.io.File; import java.io.IOException; import java.nio.file.Files; -import java.util.HashMap; import java.util.Map; import java.util.UUID; import org.junit.Before; @@ -50,19 +51,17 @@ public class AaiManagerTest { private static final String DOROTHY = "Dorothy"; private static final String SOME_URL = "http://somewhere.over.the.rainbow"; private static final String ANOTHER_URL = "http://somewhere.under.the.rainbow"; - RestManager restManagerMock; - UUID aaiNqRequestUuid = UUID.randomUUID(); - Pair httpResponseOk; - Pair httpResponseErr0; - Pair httpResponseErr1; - Pair httpResponseWait; - Pair httpTenantResponseOk; - Pair httpCqResponseOk; - private static final String TENANT_RESPONSE_SAMPLE = "src/test/resources/org/onap/policy/aai/AaiTenantResponse.json"; - + private RestManager restManagerMock; + private UUID aaiNqRequestUuid = UUID.randomUUID(); + private Pair httpResponseOk; + private Pair httpResponseErr0; + private Pair httpResponseErr1; + private Pair httpResponseWait; + private Pair httpTenantResponseOk; + private Pair httpCqResponseOk; /** * Set up test cases. @@ -73,11 +72,6 @@ public class AaiManagerTest { public void beforeTestAaiManager() throws Exception { restManagerMock = mock(RestManager.class); - Map expectedHeaders = new HashMap<>(); - expectedHeaders.put("X-FromAppId", "POLICY"); - expectedHeaders.put("X-TransactionId", aaiNqRequestUuid.toString()); - expectedHeaders.put("Accept", "application/json"); - String aaiCqResponse = new AaiCqResponseTest().getAaiCqResponse(); String tenantResponse = this.getTenantQueryResponse(); httpCqResponseOk = restManagerMock.new Pair<>(200, aaiCqResponse); @@ -235,4 +229,21 @@ public class AaiManagerTest { "Gale", vserverNameRequestId, "vnfName"); assertNotNull(vnfResponse); } + + @Test + public void testAaiManagerGetPnf() { + AaiManager aaiManager = new AaiManager(restManagerMock); + assertNotNull(aaiManager); + String pnfName = "test-pnf"; + String pnfResponse = "{\"pnf-name\":" + pnfName + + ",\"pnf-id\":\"123456\",\"in-maint\":false,\"ipaddress-v4-oam\":\"1.1.1.1\"}"; + + Pair pnfHttpResponse = restManagerMock.new Pair<>(200, pnfResponse); + when(restManagerMock.get(contains(pnfName), eq(DOROTHY), eq("Gale"), anyMap())) + .thenReturn(pnfHttpResponse); + + Map pnfParams = aaiManager.getPnf(SOME_URL, DOROTHY, "Gale", UUID.randomUUID(), pnfName); + assertNotNull(pnfParams); + assertEquals(pnfName, pnfParams.get("pnf.pnf-name")); + } } diff --git a/models-interactions/model-impl/events/src/main/java/org/onap/policy/controlloop/ControlLoopEvent.java b/models-interactions/model-impl/events/src/main/java/org/onap/policy/controlloop/ControlLoopEvent.java index 534e843f2..3ff7aa256 100644 --- a/models-interactions/model-impl/events/src/main/java/org/onap/policy/controlloop/ControlLoopEvent.java +++ b/models-interactions/model-impl/events/src/main/java/org/onap/policy/controlloop/ControlLoopEvent.java @@ -23,6 +23,7 @@ package org.onap.policy.controlloop; import com.google.gson.annotations.SerializedName; import java.io.Serializable; +import java.util.Map; import java.util.UUID; import lombok.Getter; import lombok.Setter; @@ -33,45 +34,27 @@ public abstract class ControlLoopEvent implements Serializable { private static final long serialVersionUID = 2391252138583119195L; - @SerializedName("closedLoopControlName") - private String closedLoopControlName; - - @SerializedName("version") - private String version = "1.0.2"; - @SerializedName("requestID") private UUID requestId; - - @SerializedName("closedLoopEventClient") - private String closedLoopEventClient; - @SerializedName("target_type") private String targetType; - - @SerializedName("target") + private String closedLoopControlName; + private String version = "1.0.2"; + private String closedLoopEventClient; private String target; - - @SerializedName("from") private String from; - - @SerializedName("policyScope") private String policyScope; - - @SerializedName("policyName") private String policyName; - - @SerializedName("policyVersion") private String policyVersion; - - @SerializedName("closedLoopEventStatus") private ControlLoopEventStatus closedLoopEventStatus; + private Map additionalEventParams; public ControlLoopEvent() { } /** - * Construct an instace from an existing instance. + * Construct an instance from an existing instance. * * @param event the existing instance */ @@ -79,6 +62,7 @@ public abstract class ControlLoopEvent implements Serializable { if (event == null) { return; } + this.version = event.version; this.closedLoopControlName = event.closedLoopControlName; this.requestId = event.requestId; this.closedLoopEventClient = event.closedLoopEventClient; @@ -89,6 +73,7 @@ public abstract class ControlLoopEvent implements Serializable { this.policyName = event.policyName; this.policyVersion = event.policyVersion; this.closedLoopEventStatus = event.closedLoopEventStatus; + this.additionalEventParams = event.additionalEventParams; } public boolean isEventStatusValid() { diff --git a/models-interactions/model-impl/events/src/main/java/org/onap/policy/controlloop/ControlLoopTargetType.java b/models-interactions/model-impl/events/src/main/java/org/onap/policy/controlloop/ControlLoopTargetType.java index 1ca182563..b79140a12 100644 --- a/models-interactions/model-impl/events/src/main/java/org/onap/policy/controlloop/ControlLoopTargetType.java +++ b/models-interactions/model-impl/events/src/main/java/org/onap/policy/controlloop/ControlLoopTargetType.java @@ -26,4 +26,5 @@ public class ControlLoopTargetType { public static final String VF = "VF"; public static final String VFC = "VFC"; public static final String VNF = "VNF"; + public static final String PNF = "PNF"; } diff --git a/models-interactions/model-impl/events/src/test/java/org/onap/policy/controlloop/ControlLoopTargetTypeTest.java b/models-interactions/model-impl/events/src/test/java/org/onap/policy/controlloop/ControlLoopTargetTypeTest.java index daf6bb814..ac700c866 100644 --- a/models-interactions/model-impl/events/src/test/java/org/onap/policy/controlloop/ControlLoopTargetTypeTest.java +++ b/models-interactions/model-impl/events/src/test/java/org/onap/policy/controlloop/ControlLoopTargetTypeTest.java @@ -33,5 +33,6 @@ public class ControlLoopTargetTypeTest { assertEquals("VF", ControlLoopTargetType.VF); assertEquals("VFC", ControlLoopTargetType.VFC); assertEquals("VNF", ControlLoopTargetType.VNF); + assertEquals("PNF", ControlLoopTargetType.PNF); } } -- cgit 1.2.3-korg