Adding pdpGroup to PdpRegistrationHandler 18/98718/2
authorramverma <ram.krishna.verma@est.tech>
Thu, 21 Nov 2019 14:54:43 +0000 (14:54 +0000)
committerramverma <ram.krishna.verma@est.tech>
Thu, 21 Nov 2019 17:22:50 +0000 (17:22 +0000)
Adding pdpGroup as the matching condition for registration of Pdps.
Removing the check of supported policy types in pdp heartbeat.
Adding check of policies in pdp heartbeat.
Adding comprehensive unit test coverage (98%) for the heartbeat
listener.

Issue-ID: POLICY-2231
Change-Id: I0fb961717c74656c5f1b6937b6c3a1410382a76e
Signed-off-by: ramverma <ram.krishna.verma@est.tech>
main/src/main/java/org/onap/policy/pap/main/comm/PdpStatusMessageHandler.java
main/src/test/java/org/onap/policy/pap/main/comm/PdpHeartbeatListenerTest.java [new file with mode: 0644]
main/src/test/java/org/onap/policy/pap/main/rest/e2e/End2EndBase.java
main/src/test/resources/e2e/PdpGroups.json [new file with mode: 0644]

index 09ee64d..1ea8e86 100644 (file)
@@ -22,9 +22,8 @@
 package org.onap.policy.pap.main.comm;
 
 import java.util.List;
-import java.util.Map;
 import java.util.Optional;
-import java.util.TreeMap;
+
 import org.apache.commons.lang3.builder.EqualsBuilder;
 import org.onap.policy.common.utils.services.Registry;
 import org.onap.policy.models.base.PfModelException;
@@ -73,11 +72,11 @@ public class PdpStatusMessageHandler extends PdpMessageGenerator {
                 }
 
                 /*
-                 * Indicate that a heart beat was received from the PDP. This is invoked
-                 * only if handleXxx() does not throw an exception.
+                 * Indicate that a heart beat was received from the PDP. This is invoked only if handleXxx() does not
+                 * throw an exception.
                  */
                 if (message.getName() != null) {
-                    PdpTracker pdpTracker = Registry.get(PapConstants.REG_PDP_TRACKER);
+                    final PdpTracker pdpTracker = Registry.get(PapConstants.REG_PDP_TRACKER);
                     pdpTracker.add(message.getName());
                 }
             } catch (final PolicyPapException exp) {
@@ -100,47 +99,16 @@ public class PdpStatusMessageHandler extends PdpMessageGenerator {
     private boolean findAndUpdatePdpGroup(final PdpStatus message, final PolicyModelsProvider databaseProvider)
             throws PfModelException {
         boolean pdpGroupFound = false;
-        PdpGroup emptyPdpGroup = null;
         final PdpGroupFilter filter =
-                PdpGroupFilter.builder().pdpType(message.getPdpType()).groupState(PdpState.ACTIVE).build();
+                PdpGroupFilter.builder().name(message.getPdpGroup()).groupState(PdpState.ACTIVE).build();
 
-        final TreeMap<Integer, PdpGroup> selectedPdpGroups = new TreeMap<>();
         final List<PdpGroup> pdpGroups = databaseProvider.getFilteredPdpGroups(filter);
-        emptyPdpGroup = selectPdpGroupsForRegistration(message, selectedPdpGroups, pdpGroups);
-        if (emptyPdpGroup != null) {
-            pdpGroupFound = registerPdp(message, databaseProvider, emptyPdpGroup);
-        } else if (!selectedPdpGroups.isEmpty()) {
-            final PdpGroup finalizedPdpGroup = selectedPdpGroups.lastEntry().getValue();
-            pdpGroupFound = registerPdp(message, databaseProvider, finalizedPdpGroup);
+        if (!pdpGroups.isEmpty()) {
+            pdpGroupFound = registerPdp(message, databaseProvider, pdpGroups.get(0));
         }
         return pdpGroupFound;
     }
 
-    private PdpGroup selectPdpGroupsForRegistration(final PdpStatus message,
-            final Map<Integer, PdpGroup> selectedPdpGroups, final List<PdpGroup> pdpGroups) {
-        PdpGroup emptyPdpGroup = null;
-        for (final PdpGroup pdpGroup : pdpGroups) {
-            emptyPdpGroup = selectPdpSubGroupsForRegistration(message, selectedPdpGroups, pdpGroup, emptyPdpGroup);
-        }
-        return emptyPdpGroup;
-    }
-
-    private PdpGroup selectPdpSubGroupsForRegistration(final PdpStatus message,
-                    final Map<Integer, PdpGroup> selectedPdpGroups, final PdpGroup pdpGroup, PdpGroup emptyPdpGroup) {
-        for (final PdpSubGroup pdpSubGroup : pdpGroup.getPdpSubgroups()) {
-            if (message.getSupportedPolicyTypes().containsAll(pdpSubGroup.getSupportedPolicyTypes())) {
-                if (pdpSubGroup.getCurrentInstanceCount() == 0) {
-                    emptyPdpGroup = pdpGroup;
-                } else {
-                    selectedPdpGroups.put(
-                            pdpSubGroup.getDesiredInstanceCount() - pdpSubGroup.getCurrentInstanceCount(),
-                            pdpGroup);
-                }
-            }
-        }
-        return emptyPdpGroup;
-    }
-
     private boolean registerPdp(final PdpStatus message, final PolicyModelsProvider databaseProvider,
             final PdpGroup finalizedPdpGroup) throws PfModelException {
         Optional<PdpSubGroup> subGroup;
@@ -251,15 +219,15 @@ public class PdpStatusMessageHandler extends PdpMessageGenerator {
             final Pdp pdpInstanceDetails) {
 
         /*
-         * "EqualsBuilder" is a bit of a misnomer, as it uses containsAll() to check supported policy types.
-         * Nevertheless, it does the job and provides a convenient way to build a bunch of comparisons.
+         * "EqualsBuilder" is a bit of a misnomer, as it uses containsAll() to check policies. Nevertheless, it does the
+         * job and provides a convenient way to build a bunch of comparisons.
          */
         return new EqualsBuilder().append(message.getPdpGroup(), pdpGroup.getName())
                 .append(message.getPdpSubgroup(), subGroup.getPdpType())
                 .append(message.getPdpType(), subGroup.getPdpType())
                 .append(message.getState(), pdpInstanceDetails.getPdpState())
-                .append(message.getSupportedPolicyTypes().containsAll(subGroup.getSupportedPolicyTypes()), true)
-                .build();
+                .append(message.getPolicies().containsAll(subGroup.getPolicies()), true)
+                .append(subGroup.getPolicies().containsAll(message.getPolicies()), true).build();
     }
 
     private void updatePdpHealthStatus(final PdpStatus message, final PdpSubGroup pdpSubgroup, final Pdp pdpInstance,
diff --git a/main/src/test/java/org/onap/policy/pap/main/comm/PdpHeartbeatListenerTest.java b/main/src/test/java/org/onap/policy/pap/main/comm/PdpHeartbeatListenerTest.java
new file mode 100644 (file)
index 0000000..960adc1
--- /dev/null
@@ -0,0 +1,158 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.pap.main.comm;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.Test;
+import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure;
+import org.onap.policy.common.utils.coder.CoderException;
+import org.onap.policy.models.base.PfModelException;
+import org.onap.policy.models.pdp.concepts.PdpGroup;
+import org.onap.policy.models.pdp.concepts.PdpStatus;
+import org.onap.policy.models.pdp.concepts.PdpSubGroup;
+import org.onap.policy.models.pdp.enums.PdpHealthStatus;
+import org.onap.policy.models.pdp.enums.PdpState;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifier;
+import org.onap.policy.pap.main.rest.e2e.End2EndBase;
+
+/**
+ * Class to perform unit test of {@link PdpHeartbeatListener}.
+ *
+ * @author Ram Krishna Verma (ram.krishna.verma@est.tech)
+ */
+public class PdpHeartbeatListenerTest extends End2EndBase {
+
+    private static final String POLICY_VERSION = "1.0.0";
+    private static final String POLICY_NAME = "onap.restart.tca";
+    private static final String APEX_TYPE = "apex";
+    private static final String DEFAULT_GROUP = "defaultGroup";
+    private static final String PDP_NAME = "pdp_1";
+    private static final CommInfrastructure INFRA = CommInfrastructure.NOOP;
+    private static final String TOPIC = "my-topic";
+
+    private PdpHeartbeatListener pdpHeartbeatListener;
+
+    @Test
+    public void testPdpHeartbeatListener() throws CoderException, PfModelException {
+        addGroups("PdpGroups.json");
+        pdpHeartbeatListener = new PdpHeartbeatListener();
+
+        // Testing pdp registration success case
+        final PdpStatus status1 = new PdpStatus();
+        status1.setName(PDP_NAME);
+        status1.setState(PdpState.ACTIVE);
+        status1.setPdpGroup(DEFAULT_GROUP);
+        status1.setPdpType(APEX_TYPE);
+        status1.setHealthy(PdpHealthStatus.HEALTHY);
+        final List<ToscaPolicyIdentifier> idents1 =
+                Arrays.asList(new ToscaPolicyIdentifier(POLICY_NAME, POLICY_VERSION));
+        status1.setPolicies(idents1);
+        pdpHeartbeatListener.onTopicEvent(INFRA, TOPIC, status1);
+        verifyPdpGroup(DEFAULT_GROUP, 1);
+
+        // Testing pdp heartbeat success case
+        final PdpStatus status2 = new PdpStatus();
+        status2.setName(PDP_NAME);
+        status2.setState(PdpState.ACTIVE);
+        status2.setPdpGroup(DEFAULT_GROUP);
+        status2.setPdpType(APEX_TYPE);
+        status2.setHealthy(PdpHealthStatus.HEALTHY);
+        status2.setPdpSubgroup(APEX_TYPE);
+        final List<ToscaPolicyIdentifier> idents2 =
+                Arrays.asList(new ToscaPolicyIdentifier(POLICY_NAME, POLICY_VERSION));
+        status2.setPolicies(idents2);
+        pdpHeartbeatListener.onTopicEvent(INFRA, TOPIC, status2);
+        verifyPdpGroup(DEFAULT_GROUP, 1);
+
+        // Testing pdp heartbeat failure case with pdp missing
+        final PdpStatus status3 = new PdpStatus();
+        status3.setName("pdp_2");
+        status3.setState(PdpState.ACTIVE);
+        status3.setPdpGroup(DEFAULT_GROUP);
+        status3.setPdpType(APEX_TYPE);
+        status3.setHealthy(PdpHealthStatus.HEALTHY);
+        status3.setPdpSubgroup(APEX_TYPE);
+        final List<ToscaPolicyIdentifier> idents3 =
+                Arrays.asList(new ToscaPolicyIdentifier(POLICY_NAME, POLICY_VERSION));
+        status3.setPolicies(idents3);
+        pdpHeartbeatListener.onTopicEvent(INFRA, TOPIC, status3);
+        verifyPdpGroup(DEFAULT_GROUP, 1);
+
+        // Testing pdp registration failure case
+        final PdpStatus status4 = new PdpStatus();
+        status4.setName("pdp_3");
+        status4.setState(PdpState.ACTIVE);
+        status4.setPdpGroup("wrongGroup");
+        status4.setPdpType(APEX_TYPE);
+        status4.setHealthy(PdpHealthStatus.HEALTHY);
+        final List<ToscaPolicyIdentifier> idents4 =
+                Arrays.asList(new ToscaPolicyIdentifier(POLICY_NAME, POLICY_VERSION));
+        status4.setPolicies(idents4);
+        pdpHeartbeatListener.onTopicEvent(INFRA, TOPIC, status4);
+        verifyPdpGroup(DEFAULT_GROUP, 1);
+
+        // Testing pdp heartbeat failure case with pdp mismatch
+        final PdpStatus status5 = new PdpStatus();
+        status5.setName(PDP_NAME);
+        status5.setState(PdpState.PASSIVE);
+        status5.setPdpGroup(DEFAULT_GROUP);
+        status5.setPdpType(APEX_TYPE);
+        status5.setHealthy(PdpHealthStatus.HEALTHY);
+        status5.setPdpSubgroup(APEX_TYPE);
+        final List<ToscaPolicyIdentifier> idents5 =
+                Arrays.asList(new ToscaPolicyIdentifier(POLICY_NAME, POLICY_VERSION));
+        status5.setPolicies(idents5);
+        pdpHeartbeatListener.onTopicEvent(INFRA, TOPIC, status5);
+        verifyPdpGroup(DEFAULT_GROUP, 1);
+
+        // Testing pdp termination case
+        final PdpStatus status6 = new PdpStatus();
+        status6.setName(PDP_NAME);
+        status6.setState(PdpState.TERMINATED);
+        status6.setPdpGroup(DEFAULT_GROUP);
+        status6.setPdpType(APEX_TYPE);
+        status6.setPdpSubgroup(APEX_TYPE);
+        status6.setHealthy(PdpHealthStatus.HEALTHY);
+        final List<ToscaPolicyIdentifier> idents6 =
+                Arrays.asList(new ToscaPolicyIdentifier(POLICY_NAME, POLICY_VERSION));
+        status6.setPolicies(idents6);
+        pdpHeartbeatListener.onTopicEvent(INFRA, TOPIC, status6);
+        verifyPdpGroup(DEFAULT_GROUP, 0);
+
+    }
+
+    private void verifyPdpGroup(final String name, final int count) throws PfModelException {
+        final List<PdpGroup> fetchedGroups = fetchGroups(name);
+        for (final PdpSubGroup subGroup : fetchedGroups.get(0).getPdpSubgroups()) {
+            if (subGroup.getPdpType().equals(APEX_TYPE)) {
+                assertEquals(count, subGroup.getPdpInstances().size());
+                assertEquals(count, subGroup.getCurrentInstanceCount());
+                if (count > 0) {
+                    assertEquals(PdpHealthStatus.HEALTHY, subGroup.getPdpInstances().get(0).getHealthy());
+                }
+            }
+        }
+    }
+}
index 10c791e..e6dd200 100644 (file)
@@ -1,8 +1,9 @@
-/*
+/*-
  * ============LICENSE_START=======================================================
  * ONAP PAP
  * ================================================================================
  * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2019 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -24,6 +25,8 @@ import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.util.List;
+
 import org.junit.After;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
@@ -33,6 +36,7 @@ import org.onap.policy.common.utils.coder.CoderException;
 import org.onap.policy.common.utils.coder.StandardCoder;
 import org.onap.policy.common.utils.resources.ResourceUtils;
 import org.onap.policy.models.base.PfModelException;
+import org.onap.policy.models.pdp.concepts.PdpGroup;
 import org.onap.policy.models.pdp.concepts.PdpGroups;
 import org.onap.policy.models.provider.PolicyModelsProvider;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
@@ -51,8 +55,7 @@ public class End2EndBase extends CommonPapRestServer {
     private static final Yaml yaml = new Yaml();
 
     /**
-     * DB connection. This is kept open until {@link #stop()} is invoked so that the
-     * in-memory DB is not destroyed.
+     * DB connection. This is kept open until {@link #stop()} is invoked so that the in-memory DB is not destroyed.
      */
     private static PolicyModelsProvider dbConn;
 
@@ -83,10 +86,10 @@ public class End2EndBase extends CommonPapRestServer {
      * @param shouldStart {@code true} if Main should be started, {@code false} otherwise
      * @throws Exception if an error occurs
      */
-    public static void setUpBeforeClass(boolean shouldStart) throws Exception {
+    public static void setUpBeforeClass(final boolean shouldStart) throws Exception {
         CommonPapRestServer.setUpBeforeClass(shouldStart);
 
-        PapParameterGroup params = new StandardCoder().decode(new File(CONFIG_FILE), PapParameterGroup.class);
+        final PapParameterGroup params = new StandardCoder().decode(new File(CONFIG_FILE), PapParameterGroup.class);
         daoFactory = new PolicyModelsProviderFactoryWrapper(params.getDatabaseProviderParameters());
         dbConn = daoFactory.create();
     }
@@ -98,13 +101,13 @@ public class End2EndBase extends CommonPapRestServer {
     public static void tearDownAfterClass() {
         try {
             dbConn.close();
-        } catch (PfModelException e) {
+        } catch (final PfModelException e) {
             logger.warn("failed to close the DB", e);
         }
 
         try {
             daoFactory.close();
-        } catch (Exception e) {
+        } catch (final Exception e) {
             logger.warn("failed to close DAO factory", e);
         }
 
@@ -114,12 +117,13 @@ public class End2EndBase extends CommonPapRestServer {
     /**
      * Tears down.
      */
+    @Override
     @After
     public void tearDown() {
         if (context != null) {
             try {
                 context.stop();
-            } catch (Exception e) {
+            } catch (final Exception e) {
                 logger.warn("failed to stop end-to-end context", e);
             }
             context = null;
@@ -134,8 +138,8 @@ public class End2EndBase extends CommonPapRestServer {
      * @param yamlFile name of the YAML file specifying the data to be loaded
      * @throws PfModelException if a DAO error occurs
      */
-    public static void addToscaPolicyTypes(String yamlFile) throws PfModelException {
-        ToscaServiceTemplate serviceTemplate = loadYamlFile(yamlFile, ToscaServiceTemplate.class);
+    public static void addToscaPolicyTypes(final String yamlFile) throws PfModelException {
+        final ToscaServiceTemplate serviceTemplate = loadYamlFile(yamlFile, ToscaServiceTemplate.class);
         dbConn.createPolicyTypes(serviceTemplate);
     }
 
@@ -145,8 +149,8 @@ public class End2EndBase extends CommonPapRestServer {
      * @param yamlFile name of the YAML file specifying the data to be loaded
      * @throws PfModelException if a DAO error occurs
      */
-    public static void addToscaPolicies(String yamlFile) throws PfModelException {
-        ToscaServiceTemplate serviceTemplate = loadYamlFile(yamlFile, ToscaServiceTemplate.class);
+    public static void addToscaPolicies(final String yamlFile) throws PfModelException {
+        final ToscaServiceTemplate serviceTemplate = loadYamlFile(yamlFile, ToscaServiceTemplate.class);
         dbConn.createPolicies(serviceTemplate);
     }
 
@@ -156,10 +160,10 @@ public class End2EndBase extends CommonPapRestServer {
      * @param jsonFile name of the JSON file specifying the data to be loaded
      * @throws PfModelException if a DAO error occurs
      */
-    public static void addGroups(String jsonFile) throws PfModelException {
-        PdpGroups groups = loadJsonFile(jsonFile, PdpGroups.class);
+    public static void addGroups(final String jsonFile) throws PfModelException {
+        final PdpGroups groups = loadJsonFile(jsonFile, PdpGroups.class);
 
-        ValidationResult result = groups.validatePapRest();
+        final ValidationResult result = groups.validatePapRest();
         if (!result.isValid()) {
             throw new PolicyPapRuntimeException("cannot init DB groups from " + jsonFile + ":\n" + result.getResult());
         }
@@ -167,6 +171,16 @@ public class End2EndBase extends CommonPapRestServer {
         dbConn.createPdpGroups(groups.getGroups());
     }
 
+    /**
+     * Fetch PDP groups from the DB.
+     *
+     * @param name name of the pdpGroup
+     * @throws PfModelException if a DAO error occurs
+     */
+    public static List<PdpGroup> fetchGroups(final String name) throws PfModelException {
+        return dbConn.getPdpGroups(name);
+    }
+
     /**
      * Loads an object from a YAML file.
      *
@@ -174,13 +188,13 @@ public class End2EndBase extends CommonPapRestServer {
      * @param clazz the class of the object to be loaded
      * @return the object that was loaded from the file
      */
-    protected static <T> T loadYamlFile(String fileName, Class<T> clazz) {
-        File propFile = new File(ResourceUtils.getFilePath4Resource("e2e/" + fileName));
+    protected static <T> T loadYamlFile(final String fileName, final Class<T> clazz) {
+        final File propFile = new File(ResourceUtils.getFilePath4Resource("e2e/" + fileName));
 
         try (FileInputStream input = new FileInputStream(propFile)) {
-            Object yamlObject = yaml.load(input);
-            String json = coder.encode(yamlObject);
-            T result = coder.decode(json, clazz);
+            final Object yamlObject = yaml.load(input);
+            final String json = coder.encode(yamlObject);
+            final T result = coder.decode(json, clazz);
 
             if (result == null) {
                 throw new PolicyPapRuntimeException("cannot decode " + clazz.getSimpleName() + " from " + fileName);
@@ -188,7 +202,7 @@ public class End2EndBase extends CommonPapRestServer {
 
             return result;
 
-        } catch (FileNotFoundException e) {
+        } catch (final FileNotFoundException e) {
             throw new PolicyPapRuntimeException("cannot find " + fileName, e);
 
         } catch (IOException | CoderException e) {
@@ -203,11 +217,11 @@ public class End2EndBase extends CommonPapRestServer {
      * @param clazz the class of the object to be loaded
      * @return the object that was loaded from the file
      */
-    protected static <T> T loadJsonFile(String fileName, Class<T> clazz) {
-        String fileName2 = (fileName.startsWith("src/") ? fileName : "e2e/" + fileName);
-        File propFile = new File(ResourceUtils.getFilePath4Resource(fileName2));
+    protected static <T> T loadJsonFile(final String fileName, final Class<T> clazz) {
+        final String fileName2 = (fileName.startsWith("src/") ? fileName : "e2e/" + fileName);
+        final File propFile = new File(ResourceUtils.getFilePath4Resource(fileName2));
         try {
-            T result = coder.decode(propFile, clazz);
+            final T result = coder.decode(propFile, clazz);
 
             if (result == null) {
                 throw new PolicyPapRuntimeException("cannot decode " + clazz.getSimpleName() + " from " + fileName);
@@ -215,7 +229,7 @@ public class End2EndBase extends CommonPapRestServer {
 
             return result;
 
-        } catch (CoderException e) {
+        } catch (final CoderException e) {
             throw new RuntimeException(e);
         }
     }
diff --git a/main/src/test/resources/e2e/PdpGroups.json b/main/src/test/resources/e2e/PdpGroups.json
new file mode 100644 (file)
index 0000000..a92ec06
--- /dev/null
@@ -0,0 +1,112 @@
+{
+  "groups": [
+    {
+      "name": "defaultGroup",
+      "version": "1.0.0",
+      "description": "The default group that registers all supported policy types and pdps.",
+      "pdpGroupState": "ACTIVE",
+      "pdpSubgroups": [
+        {
+          "pdpType": "xacml",
+          "supportedPolicyTypes": [
+            {
+              "name": "onap.policies.controlloop.guard.FrequencyLimiter",
+              "version": "1.0.0"
+            },
+            {
+              "name": "onap.policies.controlloop.guard.MinMax",
+              "version": "1.0.0"
+            },
+            {
+              "name": "onap.policies.controlloop.guard.Blacklist",
+              "version": "1.0.0"
+            },
+            {
+              "name": "onap.policies.controlloop.guard.coordination.FirstBlocksSecond",
+              "version": "1.0.0"
+            },
+            {
+              "name": "onap.Monitoring",
+              "version": "1.0.0"
+            },
+            {
+              "name": "onap.policies.monitoring.cdap.tca.hi.lo.app",
+              "version": "1.0.0"
+            },
+            {
+              "name": "onap.policies.monitoring.dcaegen2.collectors.datafile.datafile-app-server",
+              "version": "1.0.0"
+            },
+            {
+              "name": "onap.policies.monitoring.docker.sonhandler.app",
+              "version": "1.0.0"
+            },
+            {
+              "name": "onap.policies.optimization.AffinityPolicy",
+              "version": "1.0.0"
+            },
+            {
+              "name": "onap.policies.optimization.DistancePolicy",
+              "version": "1.0.0"
+            },
+            {
+              "name": "onap.policies.optimization.HpaPolicy",
+              "version": "1.0.0"
+            },
+            {
+              "name": "onap.policies.optimization.OptimizationPolicy",
+              "version": "1.0.0"
+            },
+            {
+              "name": "onap.policies.optimization.PciPolicy",
+              "version": "1.0.0"
+            },
+            {
+              "name": "onap.policies.optimization.QueryPolicy",
+              "version": "1.0.0"
+            },
+            {
+              "name": "onap.policies.optimization.SubscriberPolicy",
+              "version": "1.0.0"
+            },
+            {
+              "name": "onap.policies.optimization.Vim_fit",
+              "version": "1.0.0"
+            },
+            {
+              "name": "onap.policies.optimization.VnfPolicy",
+              "version": "1.0.0"
+            }
+          ],
+          "currentInstanceCount": 0,
+          "desiredInstanceCount": 1,
+          "policies": []
+        },
+        {
+          "pdpType": "drools",
+          "supportedPolicyTypes": [
+            {
+              "name": "onap.policies.controlloop.Operational",
+              "version": "1.0.0"
+            }
+          ],
+          "currentInstanceCount": 0,
+          "desiredInstanceCount": 1,
+          "policies": []
+        },
+        {
+          "pdpType": "apex",
+          "supportedPolicyTypes": [
+            {
+              "name": "onap.policies.controlloop.operational.Apex",
+              "version": "1.0.0"
+            }
+          ],
+          "currentInstanceCount": 0,
+          "desiredInstanceCount": 1,
+          "policies": []
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file