Add end-to-end junits for PAP REST API 43/85643/5
authorJim Hahn <jrh3@att.com>
Wed, 17 Apr 2019 19:30:46 +0000 (15:30 -0400)
committerJim Hahn <jrh3@att.com>
Fri, 19 Apr 2019 14:03:33 +0000 (10:03 -0400)
Added test that checks sunny day scenarios for the PAP REST API.
Uses real PAP components for everything except DMaaP.  PDPs are
simulated.

Change-Id: If2adc3b1523b477c3efd3eb83fb7a7b04f40fa24
Issue-ID: POLICY-1670
Signed-off-by: Jim Hahn <jrh3@att.com>
27 files changed:
main/src/main/java/org/onap/policy/pap/main/comm/PdpModifyRequestMap.java
main/src/main/java/org/onap/policy/pap/main/startstop/Main.java
main/src/test/java/org/onap/policy/pap/main/parameters/CommonTestData.java
main/src/test/java/org/onap/policy/pap/main/parameters/TestPapParameterGroup.java
main/src/test/java/org/onap/policy/pap/main/parameters/TestPdpParameters.java
main/src/test/java/org/onap/policy/pap/main/rest/CommonPapRestServer.java
main/src/test/java/org/onap/policy/pap/main/rest/e2e/End2EndBase.java [new file with mode: 0644]
main/src/test/java/org/onap/policy/pap/main/rest/e2e/End2EndContext.java [new file with mode: 0644]
main/src/test/java/org/onap/policy/pap/main/rest/e2e/HealthCheckTest.java [new file with mode: 0644]
main/src/test/java/org/onap/policy/pap/main/rest/e2e/PdpGroupDeleteTest.java [new file with mode: 0644]
main/src/test/java/org/onap/policy/pap/main/rest/e2e/PdpGroupDeployTest.java [new file with mode: 0644]
main/src/test/java/org/onap/policy/pap/main/rest/e2e/PdpGroupQueryTest.java [new file with mode: 0644]
main/src/test/java/org/onap/policy/pap/main/rest/e2e/PdpGroupStateChangeTest.java [new file with mode: 0644]
main/src/test/java/org/onap/policy/pap/main/rest/e2e/StatisticsTest.java [new file with mode: 0644]
main/src/test/resources/e2e/PapConfigParameters.json [new file with mode: 0644]
main/src/test/resources/e2e/createGroups.json [new file with mode: 0644]
main/src/test/resources/e2e/deleteGroup.json [new file with mode: 0644]
main/src/test/resources/e2e/deployPolicies.json [new file with mode: 0644]
main/src/test/resources/e2e/deployPoliciesReq.json [new file with mode: 0644]
main/src/test/resources/e2e/monitoring.policy-type.yaml [new file with mode: 0644]
main/src/test/resources/e2e/monitoring.policy.yaml [new file with mode: 0644]
main/src/test/resources/e2e/queryGroup.json [new file with mode: 0644]
main/src/test/resources/e2e/stateChangeGroupDeactivate.json [new file with mode: 0644]
main/src/test/resources/e2e/undeployPolicy.json [new file with mode: 0644]
main/src/test/resources/e2e/undeployPolicyVersion.json [new file with mode: 0644]
main/src/test/resources/logback-test.xml [new file with mode: 0644]
main/src/test/resources/parameters/PapConfigParametersStd.json [new file with mode: 0644]

index 8dcb979..a11a4e7 100644 (file)
@@ -89,6 +89,15 @@ public class PdpModifyRequestMap {
         this.daoFactory = params.getDaoFactory();
     }
 
+    /**
+     * Determines if the map contains any requests.
+     *
+     * @return {@code true} if the map is empty, {@code false} otherwise
+     */
+    public boolean isEmpty() {
+        return pdp2requests.isEmpty();
+    }
+
     /**
      * Stops publishing requests to the given PDP.
      *
index e8b48e6..6351fa8 100644 (file)
@@ -153,6 +153,10 @@ public class Main {
          */
         @Override
         public void run() {
+            if (!activator.isAlive()) {
+                return;
+            }
+
             try {
                 // Shutdown the policy pap service and wait for everything to stop
                 activator.stop();
index 10e500f..14000e6 100644 (file)
 
 package org.onap.policy.pap.main.parameters;
 
-import java.util.Base64;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.TreeMap;
-
-import org.onap.policy.common.parameters.ParameterGroup;
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
 import org.onap.policy.common.utils.coder.Coder;
 import org.onap.policy.common.utils.coder.CoderException;
 import org.onap.policy.common.utils.coder.StandardCoder;
-import org.onap.policy.models.provider.PolicyModelsProviderParameters;
-import org.onap.policy.models.provider.impl.DatabasePolicyModelsProviderImpl;
+import org.onap.policy.pap.main.PolicyPapRuntimeException;
+import org.onap.policy.pap.main.rest.e2e.End2EndBase;
 
 /**
  * Class to hold/create all parameters for test cases.
@@ -39,144 +37,79 @@ import org.onap.policy.models.provider.impl.DatabasePolicyModelsProviderImpl;
  * @author Ram Krishna Verma (ram.krishna.verma@est.tech)
  */
 public class CommonTestData {
-
-    private static final String REST_SERVER_PASSWORD = "zb!XztG34";
-    private static final String REST_SERVER_USER = "healthcheck";
-    private static final int REST_SERVER_PORT = 6969;
-    private static final String REST_SERVER_HOST = "0.0.0.0";
-    private static final boolean REST_SERVER_HTTPS = true;
-    private static final boolean REST_SERVER_AAF = false;
     public static final String PAP_GROUP_NAME = "PapGroup";
 
     private static final Coder coder = new StandardCoder();
 
-    /**
-     * Converts the contents of a map to a parameter class.
-     *
-     * @param source property map
-     * @param clazz class of object to be created from the map
-     * @return a new object represented by the map
-     */
-    public <T extends ParameterGroup> T toObject(final Map<String, Object> source, final Class<T> clazz) {
-        try {
-            return coder.decode(coder.encode(source), clazz);
+    private static int dbNum = 0;
 
-        } catch (final CoderException e) {
-            throw new RuntimeException("cannot create " + clazz.getName() + " from map", e);
-        }
+    public static void newDb() {
+        ++dbNum;
     }
 
     /**
-     * Returns a property map for a PapParameterGroup map for test cases.
+     * Gets the standard PAP parameters.
      *
-     * @param name name of the parameters
-     *
-     * @return a property map suitable for constructing an object
+     * @param port port to be inserted into the parameters
+     * @return the standard PAP parameters
      */
-    public Map<String, Object> getPapParameterGroupMap(final String name) {
-        final Map<String, Object> map = new TreeMap<>();
-
-        map.put("name", name);
-        map.put("restServerParameters", getRestServerParametersMap(false));
-        map.put("pdpParameters", getPdpParametersMap());
-        map.put("databaseProviderParameters", getPolicyModelsProviderParametersMap());
-
-        return map;
-    }
+    public PapParameterGroup getPapParameterGroup(int port) {
+        try {
+            return coder.decode(getPapParameterGroupAsString(port), PapParameterGroup.class);
 
-    /**
-     * Returns a property map for a RestServerParameters map for test cases.
-     *
-     * @param isEmpty boolean value to represent that object created should be empty or not
-     * @return a property map suitable for constructing an object
-     */
-    public Map<String, Object> getRestServerParametersMap(final boolean isEmpty) {
-        final Map<String, Object> map = new TreeMap<>();
-        map.put("https", REST_SERVER_HTTPS);
-        map.put("aaf", REST_SERVER_AAF);
-
-        if (!isEmpty) {
-            map.put("host", REST_SERVER_HOST);
-            map.put("port", REST_SERVER_PORT);
-            map.put("userName", REST_SERVER_USER);
-            map.put("password", REST_SERVER_PASSWORD);
+        } catch (CoderException e) {
+            throw new PolicyPapRuntimeException("cannot read PAP parameters", e);
         }
-
-        return map;
     }
 
     /**
-     * Returns a property map for a PdpParameters map for test cases.
+     * Gets the standard PAP parameters, as a String.
      *
-     * @return a property map suitable for constructing an object
+     * @param port port to be inserted into the parameters
+     * @return the standard PAP parameters
      */
-    public Map<String, Object> getPdpParametersMap() {
-        final Map<String, Object> map = new TreeMap<>();
+    public String getPapParameterGroupAsString(int port) {
 
-        map.put("updateParameters", getPdpUpdateParametersMap());
-        map.put("stateChangeParameters", getPdpStateChangeParametersMap());
-
-        return map;
-    }
+        try {
+            File file = new File(getParamFile());
+            String json = new String(Files.readAllBytes(file.toPath()), StandardCharsets.UTF_8);
 
-    /**
-     * Returns a property map for a PdpUpdateParameters map for test cases.
-     *
-     * @return a property map suitable for constructing an object
-     */
-    public Map<String, Object> getPdpUpdateParametersMap() {
-        return getPdpRequestParametersMap();
-    }
+            json = json.replace("${port}", String.valueOf(port));
+            json = json.replace("${dbName}", "jdbc:h2:mem:testdb" + dbNum);
 
-    /**
-     * Returns a property map for a PdpStateChangeParameters map for test cases.
-     *
-     * @return a property map suitable for constructing an object
-     */
-    public Map<String, Object> getPdpStateChangeParametersMap() {
-        return getPdpRequestParametersMap();
-    }
+            return json;
 
-    /**
-     * Returns a property map for a PdpParameters map for test cases.
-     *
-     * @return a property map suitable for constructing an object
-     */
-    public Map<String, Object> getPdpRequestParametersMap() {
-        final Map<String, Object> map = new HashMap<>();
-        map.put("maxRetryCount", "1");
-        map.put("maxWaitMs", "2");
-
-        return map;
+        } catch (IOException e) {
+            throw new PolicyPapRuntimeException("cannot read PAP parameters", e);
+        }
     }
 
     /**
-     * Returns a property map for a PdpGroupDeploymentParameters map for test cases.
+     * Gets the full path to the parameter file, which may vary depending on whether or
+     * not this is an end-to-end test.
      *
-     * @return a property map suitable for constructing an object
+     * @return the parameter file name
      */
-    public Map<String, Object> getPdpGroupDeploymentParametersMap() {
-        final Map<String, Object> map = new TreeMap<>();
-        map.put("waitResponseMs", "1");
-
-        return map;
+    private String getParamFile() {
+        String paramFile = "src/test/resources/parameters/PapConfigParametersStd.json";
+
+        for (StackTraceElement stack : Thread.currentThread().getStackTrace()) {
+            String classnm = stack.getClassName();
+            if (End2EndBase.class.getName().equals(classnm)) {
+                paramFile = "src/test/resources/e2e/PapConfigParameters.json";
+                break;
+            }
+        }
+        return paramFile;
     }
 
     /**
-     * Returns a property map for a PolicyModelsProviderParameters map for test cases.
-     *
-     * @return a property map suitable for constructing an object
+     * Nulls out a field within a JSON string.
+     * @param json JSON string
+     * @param field field to be nulled out
+     * @return a new JSON string with the field nulled out
      */
-    public Map<String, Object> getPolicyModelsProviderParametersMap() {
-        final Map<String, Object> map = new TreeMap<>();
-        map.put("name", PolicyModelsProviderParameters.class.getSimpleName());
-        map.put("implementation", DatabasePolicyModelsProviderImpl.class.getName());
-        map.put("databaseDriver", "org.h2.Driver");
-        map.put("databaseUrl", "jdbc:h2:mem:testdb");
-        map.put("databaseUser", "policy");
-        map.put("databasePassword", Base64.getEncoder().encodeToString("P01icY".getBytes()));
-        map.put("persistenceUnit", "ToscaConceptTest");
-
-        return map;
+    public String nullifyField(String json, String field) {
+        return json.replace(field + "\"", field + "\":null, \"" + field + "Xxx\"");
     }
 }
index 2450a75..6a1fbba 100644 (file)
@@ -25,9 +25,10 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
-import java.util.Map;
 import org.junit.Test;
 import org.onap.policy.common.parameters.GroupValidationResult;
+import org.onap.policy.common.utils.coder.Coder;
+import org.onap.policy.common.utils.coder.StandardCoder;
 
 /**
  * Class to perform unit test of {@link PapParameterGroup}.
@@ -35,6 +36,8 @@ import org.onap.policy.common.parameters.GroupValidationResult;
  * @author Ram Krishna Verma (ram.krishna.verma@est.tech)
  */
 public class TestPapParameterGroup {
+    private static final Coder coder = new StandardCoder();
+
     CommonTestData commonTestData = new CommonTestData();
 
     @Test
@@ -45,8 +48,7 @@ public class TestPapParameterGroup {
 
     @Test
     public void testPapParameterGroup() {
-        final PapParameterGroup papParameters = commonTestData.toObject(
-                        commonTestData.getPapParameterGroupMap(CommonTestData.PAP_GROUP_NAME), PapParameterGroup.class);
+        final PapParameterGroup papParameters = commonTestData.getPapParameterGroup(1);
         final RestServerParameters restServerParameters = papParameters.getRestServerParameters();
         final GroupValidationResult validationResult = papParameters.validate();
         assertTrue(validationResult.isValid());
@@ -60,9 +62,9 @@ public class TestPapParameterGroup {
     }
 
     @Test
-    public void testPapParameterGroup_NullName() {
-        final PapParameterGroup papParameters = commonTestData.toObject(
-                        commonTestData.getPapParameterGroupMap(null), PapParameterGroup.class);
+    public void testPapParameterGroup_NullName() throws Exception {
+        String json = commonTestData.getPapParameterGroupAsString(1).replace("\"PapGroup\"", "null");
+        final PapParameterGroup papParameters = coder.decode(json, PapParameterGroup.class);
         final GroupValidationResult validationResult = papParameters.validate();
         assertFalse(validationResult.isValid());
         assertEquals(null, papParameters.getName());
@@ -70,9 +72,9 @@ public class TestPapParameterGroup {
     }
 
     @Test
-    public void testPapParameterGroup_EmptyName() {
-        final PapParameterGroup papParameters = commonTestData.toObject(
-                        commonTestData.getPapParameterGroupMap(""), PapParameterGroup.class);
+    public void testPapParameterGroup_EmptyName() throws Exception {
+        String json = commonTestData.getPapParameterGroupAsString(1).replace(CommonTestData.PAP_GROUP_NAME, "");
+        final PapParameterGroup papParameters = coder.decode(json, PapParameterGroup.class);
         final GroupValidationResult validationResult = papParameters.validate();
         assertFalse(validationResult.isValid());
         assertEquals("", papParameters.getName());
@@ -82,8 +84,7 @@ public class TestPapParameterGroup {
 
     @Test
     public void testPapParameterGroup_SetName() {
-        final PapParameterGroup papParameters = commonTestData.toObject(
-                        commonTestData.getPapParameterGroupMap(CommonTestData.PAP_GROUP_NAME), PapParameterGroup.class);
+        final PapParameterGroup papParameters = commonTestData.getPapParameterGroup(1);
         papParameters.setName("PapNewGroup");
         final GroupValidationResult validationResult = papParameters.validate();
         assertTrue(validationResult.isValid());
@@ -91,12 +92,10 @@ public class TestPapParameterGroup {
     }
 
     @Test
-    public void testApiParameterGroup_EmptyRestServerParameters() {
-        Map<String, Object> map = commonTestData.getPapParameterGroupMap(CommonTestData.PAP_GROUP_NAME);
-        map.put("restServerParameters", commonTestData.getRestServerParametersMap(true));
-
-        final PapParameterGroup papParameters = commonTestData.toObject(
-                        map, PapParameterGroup.class);
+    public void testApiParameterGroup_EmptyRestServerParameters() throws Exception {
+        String json = commonTestData.getPapParameterGroupAsString(1);
+        json = commonTestData.nullifyField(json, "restServerParameters");
+        final PapParameterGroup papParameters = commonTestData.getPapParameterGroup(0);
         final GroupValidationResult validationResult = papParameters.validate();
         assertFalse(validationResult.isValid());
         assertTrue(validationResult.getResult()
index 05bcc10..eb9a6e8 100644 (file)
@@ -26,16 +26,18 @@ import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
-import java.util.Map;
 import org.junit.Test;
 import org.onap.policy.common.parameters.GroupValidationResult;
+import org.onap.policy.common.utils.coder.Coder;
+import org.onap.policy.common.utils.coder.StandardCoder;
 
 public class TestPdpParameters {
-    private static CommonTestData testData = new CommonTestData();
+    private static final Coder coder = new StandardCoder();
+    private static final CommonTestData testData = new CommonTestData();
 
     @Test
     public void testGetters() {
-        PdpParameters params = testData.toObject(testData.getPdpParametersMap(), PdpParameters.class);
+        PdpParameters params = testData.getPapParameterGroup(1).getPdpParameters();
 
         PdpUpdateParameters update = params.getUpdateParameters();
         assertNotNull(update);
@@ -43,53 +45,46 @@ public class TestPdpParameters {
 
         PdpStateChangeParameters state = params.getStateChangeParameters();
         assertNotNull(state);
-        assertEquals(2, state.getMaxWaitMs());
+        assertEquals(5, state.getMaxWaitMs());
     }
 
     @Test
-    public void testValidate() {
+    public void testValidate() throws Exception {
+        String json = testData.getPapParameterGroupAsString(1);
+
         // valid
-        Map<String, Object> map = testData.getPdpParametersMap();
-        GroupValidationResult result = testData.toObject(map, PdpParameters.class).validate();
+        String json2 = json;
+        GroupValidationResult result = coder.decode(json2, PapParameterGroup.class).getPdpParameters().validate();
         assertNull(result.getResult());
         assertTrue(result.isValid());
 
         // no update params
-        map = testData.getPdpParametersMap();
-        map.remove("updateParameters");
-        result = testData.toObject(map, PdpParameters.class).validate();
+        json2 = testData.nullifyField(json, "updateParameters");
+        result = coder.decode(json2, PapParameterGroup.class).getPdpParameters().validate();
         assertFalse(result.isValid());
         assertTrue(result.getResult().contains("field 'updateParameters'".replace('\'', '"')));
         assertTrue(result.getResult().contains("is null"));
 
         // invalid update params
-        map = testData.getPdpParametersMap();
-        @SuppressWarnings("unchecked")
-        Map<String, Object> updmap = (Map<String, Object>) map.get("updateParameters");
-        updmap.put("maxRetryCount", "-2");
-        result = testData.toObject(map, PdpParameters.class).validate();
+        json2 = json.replaceFirst("2", "-2");
+        result = coder.decode(json2, PapParameterGroup.class).getPdpParameters().validate();
         assertFalse(result.isValid());
         assertTrue(result.getResult().contains("parameter group 'PdpUpdateParameters'".replace('\'', '"')));
         assertTrue(result.getResult().contains(
-                        "field 'maxRetryCount' type 'int' value '-2' INVALID, must be >= 0".replace('\'', '"')));
+                        "field 'maxWaitMs' type 'long' value '-2' INVALID, must be >= 0".replace('\'', '"')));
 
         // no state-change params
-        map = testData.getPdpParametersMap();
-        map.remove("stateChangeParameters");
-        result = testData.toObject(map, PdpParameters.class).validate();
+        json2 = testData.nullifyField(json, "stateChangeParameters");
+        result = coder.decode(json2, PapParameterGroup.class).getPdpParameters().validate();
         assertFalse(result.isValid());
 
         // invalid state-change params
-        map = testData.getPdpParametersMap();
-        @SuppressWarnings("unchecked")
-        Map<String, Object> statemap = (Map<String, Object>) map.get("stateChangeParameters");
-        statemap.put("maxRetryCount", "-3");
-        result = testData.toObject(map, PdpParameters.class).validate();
+        json2 = json.replaceFirst("5", "-5");
+        result = coder.decode(json2, PapParameterGroup.class).getPdpParameters().validate();
         assertFalse(result.isValid());
-        System.out.println(result.getResult());
         assertTrue(result.getResult().contains("parameter group 'PdpStateChangeParameters'".replace('\'', '"')));
         assertTrue(result.getResult().contains(
-                        "field 'maxRetryCount' type 'int' value '-3' INVALID, must be >= 0".replace('\'', '"')));
+                        "field 'maxWaitMs' type 'long' value '-5' INVALID, must be >= 0".replace('\'', '"')));
     }
 
 }
index e7b412d..d4b69f2 100644 (file)
@@ -25,8 +25,9 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
 import java.io.File;
+import java.io.FileOutputStream;
+import java.nio.charset.StandardCharsets;
 import java.security.SecureRandom;
-import java.util.Map;
 import java.util.Properties;
 import java.util.function.Function;
 import javax.net.ssl.SSLContext;
@@ -42,10 +43,9 @@ import org.junit.After;
 import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.BeforeClass;
+import org.onap.policy.common.endpoints.event.comm.TopicEndpoint;
 import org.onap.policy.common.endpoints.http.server.HttpServletServer;
 import org.onap.policy.common.gson.GsonMessageBodyHandler;
-import org.onap.policy.common.utils.coder.Coder;
-import org.onap.policy.common.utils.coder.StandardCoder;
 import org.onap.policy.common.utils.network.NetworkUtil;
 import org.onap.policy.common.utils.services.Registry;
 import org.onap.policy.pap.main.PapConstants;
@@ -68,8 +68,6 @@ public class CommonPapRestServer {
 
     private static String KEYSTORE = System.getProperty("user.dir") + "/src/test/resources/ssl/policy-keystore";
 
-    private static Coder coder = new StandardCoder();
-
     public static final String NOT_ALIVE = "not alive";
     public static final String ALIVE = "alive";
     public static final String SELF = "self";
@@ -97,6 +95,9 @@ public class CommonPapRestServer {
         makeConfigFile();
 
         HttpServletServer.factory.destroy();
+        TopicEndpoint.manager.shutdown();
+
+        CommonTestData.newDb();
 
         startMain();
     }
@@ -156,16 +157,14 @@ public class CommonPapRestServer {
      * @throws Exception if an error occurs
      */
     private static void makeConfigFile() throws Exception {
-        Map<String, Object> config = new CommonTestData().getPapParameterGroupMap("PapGroup");
-
-        @SuppressWarnings("unchecked")
-        Map<String, Object> restParams = (Map<String, Object>) config.get("restServerParameters");
-        restParams.put("port", port);
+        String json = new CommonTestData().getPapParameterGroupAsString(port);
 
         File file = new File("src/test/resources/parameters/TestConfigParams.json");
         file.deleteOnExit();
 
-        coder.encode(file, config);
+        try (FileOutputStream output = new FileOutputStream(file)) {
+            output.write(json.getBytes(StandardCharsets.UTF_8));
+        }
     }
 
     /**
diff --git a/main/src/test/java/org/onap/policy/pap/main/rest/e2e/End2EndBase.java b/main/src/test/java/org/onap/policy/pap/main/rest/e2e/End2EndBase.java
new file mode 100644 (file)
index 0000000..7e21742
--- /dev/null
@@ -0,0 +1,217 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP PAP
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.pap.main.rest.e2e;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.onap.policy.common.parameters.ValidationResult;
+import org.onap.policy.common.utils.coder.Coder;
+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.common.utils.services.Registry;
+import org.onap.policy.models.base.PfModelException;
+import org.onap.policy.models.pdp.concepts.PdpGroups;
+import org.onap.policy.models.provider.PolicyModelsProvider;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
+import org.onap.policy.pap.main.PapConstants;
+import org.onap.policy.pap.main.PolicyModelsProviderFactoryWrapper;
+import org.onap.policy.pap.main.PolicyPapRuntimeException;
+import org.onap.policy.pap.main.rest.CommonPapRestServer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.yaml.snakeyaml.Yaml;
+
+public class End2EndBase extends CommonPapRestServer {
+    private static final Logger logger = LoggerFactory.getLogger(End2EndBase.class);
+
+    private static final Coder coder = new StandardCoder();
+    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.
+     */
+    private static PolicyModelsProvider dbConn;
+
+    /**
+     * DAO provider factory.
+     */
+    private static PolicyModelsProviderFactoryWrapper daoFactory;
+
+    /**
+     * Context - should be initialized by setUp() method.
+     */
+    protected End2EndContext context = null;
+
+
+    /**
+     * Starts Main and connects to the DB.
+     *
+     * @throws Exception if an error occurs
+     */
+    @BeforeClass
+    public static void setUpBeforeClass() throws Exception {
+        CommonPapRestServer.setUpBeforeClass();
+
+        daoFactory = Registry.get(PapConstants.REG_PAP_DAO_FACTORY, PolicyModelsProviderFactoryWrapper.class);
+
+        try {
+            dbConn = daoFactory.create();
+        } catch (PfModelException e) {
+            throw new PolicyPapRuntimeException("cannot connect to DB", e);
+        }
+    }
+
+    /**
+     * Tears down.
+     */
+    @AfterClass
+    public static void tearDownAfterClass() {
+        try {
+            dbConn.close();
+        } catch (PfModelException e) {
+            logger.warn("failed to close the DB", e);
+        }
+
+        try {
+            daoFactory.close();
+        } catch (Exception e) {
+            logger.warn("failed to close DAO factory", e);
+        }
+
+        CommonPapRestServer.teardownAfterClass();
+    }
+
+    /**
+     * Tears down.
+     */
+    @After
+    public void tearDown() {
+        if (context != null) {
+            try {
+                context.stop();
+            } catch (Exception e) {
+                logger.warn("failed to stop end-to-end context", e);
+            }
+            context = null;
+        }
+
+        super.tearDown();
+    }
+
+    /**
+     * Adds Tosca Policy Types to the DB.
+     *
+     * @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);
+        dbConn.createPolicyTypes(serviceTemplate);
+    }
+
+    /**
+     * Adds Tosca Policies to the DB.
+     *
+     * @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);
+        dbConn.createPolicies(serviceTemplate);
+    }
+
+    /**
+     * Adds PDP groups to the DB.
+     *
+     * @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);
+
+        ValidationResult result = groups.validatePapRest();
+        if (!result.isValid()) {
+            throw new PolicyPapRuntimeException("cannot init DB groups from " + jsonFile + ":\n" + result.getResult());
+        }
+
+        dbConn.createPdpGroups(groups.getGroups());
+    }
+
+    /**
+     * Loads an object from a YAML file.
+     *
+     * @param fileName name of the file from which to load
+     * @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));
+
+        try (FileInputStream input = new FileInputStream(propFile)) {
+            Object yamlObject = yaml.load(input);
+            String json = coder.encode(yamlObject);
+            T result = coder.decode(json, clazz);
+
+            if (result == null) {
+                throw new PolicyPapRuntimeException("cannot decode " + clazz.getSimpleName() + " from " + fileName);
+            }
+
+            return result;
+
+        } catch (FileNotFoundException e) {
+            throw new PolicyPapRuntimeException("cannot find " + fileName, e);
+
+        } catch (IOException | CoderException e) {
+            throw new PolicyPapRuntimeException("cannot decode " + fileName, e);
+        }
+    }
+
+    /**
+     * Loads an object from a JSON file.
+     *
+     * @param fileName name of the file from which to load
+     * @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));
+        try {
+            T result = coder.decode(propFile, clazz);
+
+            if (result == null) {
+                throw new PolicyPapRuntimeException("cannot decode " + clazz.getSimpleName() + " from " + fileName);
+            }
+
+            return result;
+
+        } catch (CoderException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/main/src/test/java/org/onap/policy/pap/main/rest/e2e/End2EndContext.java b/main/src/test/java/org/onap/policy/pap/main/rest/e2e/End2EndContext.java
new file mode 100644 (file)
index 0000000..fe0f682
--- /dev/null
@@ -0,0 +1,447 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP PAP
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.pap.main.rest.e2e;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Queue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import lombok.Getter;
+import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure;
+import org.onap.policy.common.endpoints.event.comm.TopicEndpoint;
+import org.onap.policy.common.endpoints.event.comm.TopicListener;
+import org.onap.policy.common.endpoints.event.comm.bus.NoopTopicSource;
+import org.onap.policy.common.endpoints.listeners.MessageTypeDispatcher;
+import org.onap.policy.common.endpoints.listeners.ScoListener;
+import org.onap.policy.common.utils.coder.Coder;
+import org.onap.policy.common.utils.coder.CoderException;
+import org.onap.policy.common.utils.coder.StandardCoder;
+import org.onap.policy.common.utils.coder.StandardCoderObject;
+import org.onap.policy.common.utils.services.Registry;
+import org.onap.policy.models.pdp.concepts.PdpMessage;
+import org.onap.policy.models.pdp.concepts.PdpResponseDetails;
+import org.onap.policy.models.pdp.concepts.PdpStateChange;
+import org.onap.policy.models.pdp.concepts.PdpStatus;
+import org.onap.policy.models.pdp.concepts.PdpUpdate;
+import org.onap.policy.models.pdp.enums.PdpMessageType;
+import org.onap.policy.pap.main.PapConstants;
+import org.onap.policy.pap.main.comm.PdpModifyRequestMap;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Context for end-to-end tests.
+ */
+public class End2EndContext {
+    private static final Logger logger = LoggerFactory.getLogger(End2EndContext.class);
+
+    /**
+     * Message placed onto a queue to indicate that a PDP has nothing more to do.
+     */
+    private static final String DONE = "";
+
+    /**
+     * Time, in milliseconds, to wait for everything to complete.
+     */
+    private static final long WAIT_MS = 10000;
+
+    /**
+     * Messages to be sent to PAP. Messages are removed from the queue by the ToPapThread
+     * and directly handed off to the NOOP source.
+     */
+    private final BlockingQueue<String> toPap = new LinkedBlockingQueue<>();
+
+    /**
+     * Messages to be sent to the PDPs. Messages are removed from the queue by the
+     * ToPdpThread and are given to each PDP to handle.
+     */
+    private final BlockingQueue<String> toPdps = new LinkedBlockingQueue<>();
+
+    /**
+     * List of simulated PDPs.
+     */
+    @Getter
+    private final List<PseudoPdp> pdps = new ArrayList<>();
+
+    /**
+     * PAP's topic source.
+     */
+    private final NoopTopicSource toPapTopic;
+
+    /**
+     * Decodes messages read from the {@link #toPdps} queue and dispatches them to the
+     * appropriate handler.
+     */
+    private final MessageTypeDispatcher dispatcher;
+
+    /**
+     * Thread that passes messages to PAP.
+     */
+    private final ToPapThread toPapThread;
+
+    /**
+     * Thread that passes messages to PDPs.
+     */
+    private final ToPdpsThread toPdpsThread;
+
+    /**
+     * {@code True} if started, {@code false} if stopped.
+     */
+    private boolean running = false;
+
+    /**
+     * Exception thrown by a coder. Should be {@code null} if all is OK.
+     */
+    private volatile CoderException exception = null;
+
+    /**
+     * Listener for messages written to the PDP-PAP topic.
+     */
+    private TopicListener topicListener = (infra, topic, text) -> toPdps.add(text);
+
+
+    /**
+     * Constructs the object.
+     */
+    public End2EndContext() {
+        toPapTopic = TopicEndpoint.manager.getNoopTopicSource(PapConstants.TOPIC_POLICY_PDP_PAP);
+
+        TopicEndpoint.manager.getNoopTopicSink(PapConstants.TOPIC_POLICY_PDP_PAP).register(topicListener);
+
+        dispatcher = new MessageTypeDispatcher("messageName");
+        dispatcher.register(PdpMessageType.PDP_UPDATE.name(), new UpdateListener());
+        dispatcher.register(PdpMessageType.PDP_STATE_CHANGE.name(), new ChangeListener());
+
+        toPapThread = new ToPapThread();
+        toPdpsThread = new ToPdpsThread();
+    }
+
+    /**
+     * Starts the threads that read the "DMaaP" queues..
+     */
+    public void startThreads() {
+        if (running) {
+            throw new IllegalStateException("already running");
+        }
+
+        for (Thread thread : new Thread[] {toPapThread, toPdpsThread}) {
+            thread.setDaemon(true);
+            thread.start();
+        }
+
+        running = true;
+    }
+
+    /**
+     * Waits for the threads to shut down.
+     *
+     * @throws InterruptedException if interrupted while waiting
+     */
+    public void await() throws InterruptedException {
+        toPapThread.join(WAIT_MS);
+        assertFalse(toPapThread.isAlive());
+
+        PdpModifyRequestMap map = Registry.get(PapConstants.REG_PDP_MODIFY_MAP);
+        assertTrue(map.isEmpty());
+
+        // no more requests, thus we can tell the other thread to stop
+        toPdps.add(DONE);
+
+        toPdpsThread.join(WAIT_MS);
+        assertFalse(toPapThread.isAlive());
+
+        // nothing new should have been added to the PAP queue
+        assertTrue(toPap.isEmpty());
+
+        assertNull(exception);
+    }
+
+    /**
+     * Stops the threads and shuts down the PAP Activator, rest services, and topic end
+     * points.
+     */
+    public void stop() {
+        if (!running) {
+            throw new IllegalStateException("not running");
+        }
+
+        running = false;
+
+        // queue up a "done" message for each PDP
+        toPdps.clear();
+        pdps.forEach(pdp -> toPdps.add(DONE));
+
+        // queue up a "done" message for each PDP
+        toPap.clear();
+        pdps.forEach(pdp -> toPap.add(DONE));
+
+        TopicEndpoint.manager.getNoopTopicSink(PapConstants.TOPIC_POLICY_PDP_PAP).unregister(topicListener);
+    }
+
+    /**
+     * Adds a simulated PDP. This must be called before {@link #startThreads()} is
+     * invoked.
+     *
+     * @param pdpName PDP name
+     * @param pdpType PDP type
+     * @return a new, simulated PDP
+     * @throws IllegalStateException if {@link #startThreads()} has already been invoked
+     */
+    public PseudoPdp addPdp(String pdpName, String pdpType) {
+        if (running) {
+            throw new IllegalStateException("not running");
+        }
+
+        PseudoPdp pdp = new PseudoPdp(pdpName);
+        pdps.add(pdp);
+
+        return pdp;
+    }
+
+    /**
+     * Thread that reads messages from the {@link End2EndContext#toPdps} queue and
+     * dispatches them to each PDP. This thread terminates as soon as it sees a
+     * {@link End2EndContext#DONE} message.
+     */
+    private class ToPdpsThread extends Thread {
+        @Override
+        public void run() {
+            for (;;) {
+                String text;
+                try {
+                    text = toPdps.take();
+                } catch (InterruptedException e) {
+                    logger.warn("{} interrupted", ToPdpsThread.class.getName(), e);
+                    Thread.currentThread().interrupt();
+                    break;
+                }
+
+                if (DONE.equals(text)) {
+                    break;
+                }
+
+                dispatcher.onTopicEvent(CommInfrastructure.NOOP, PapConstants.TOPIC_POLICY_PDP_PAP, text);
+            }
+        }
+    }
+
+    /**
+     * Thread that reads messages from the {@link End2EndContext#toPap} queue and passes
+     * them to the PAP's topic source. This thread terminates once it sees a
+     * {@link End2EndContext#DONE} message <i>for each PDP</i>.
+     */
+    private class ToPapThread extends Thread {
+        /**
+         * Number of DONE messages that have been received.
+         */
+        private long ndone;
+
+        @Override
+        public void run() {
+            // pretend we received DONE from PDPs that are already finished
+            ndone = pdps.stream().filter(pdp -> pdp.finished).count();
+
+            while (ndone < pdps.size()) {
+                String text;
+                try {
+                    text = toPap.take();
+                } catch (InterruptedException e) {
+                    logger.warn("{} interrupted", ToPapThread.class.getName(), e);
+                    Thread.currentThread().interrupt();
+                    break;
+                }
+
+                if (DONE.equals(text)) {
+                    ++ndone;
+
+                } else {
+                    toPapTopic.offer(text);
+                }
+            }
+        }
+    }
+
+    /**
+     * Listener for PdpUpdate messages received from PAP. Invokes
+     * {@link PseudoPdp#handle(PdpUpdate)} for each PDP.
+     */
+    private class UpdateListener extends ScoListener<PdpUpdate> {
+        public UpdateListener() {
+            super(PdpUpdate.class);
+        }
+
+        @Override
+        public void onTopicEvent(CommInfrastructure infra, String topic, StandardCoderObject sco, PdpUpdate update) {
+            pdps.forEach(pdp -> pdp.handle(update));
+        }
+    }
+
+    /**
+     * Listener for PdpStateChange messages received from PAP. Invokes
+     * {@link PseudoPdp#handle(PdpStateChange)} for each PDP.
+     */
+    private class ChangeListener extends ScoListener<PdpStateChange> {
+        public ChangeListener() {
+            super(PdpStateChange.class);
+        }
+
+        @Override
+        public void onTopicEvent(CommInfrastructure infra, String topic, StandardCoderObject sco,
+                        PdpStateChange change) {
+            pdps.forEach(pdp -> pdp.handle(change));
+        }
+    }
+
+    /**
+     * Simulated PDP. Each PDP handles messages from the PAP and can return replies in
+     * response to those messages. The replies must be queued up before
+     * {@link End2EndContext#startThreads()} is invoked.
+     */
+    public class PseudoPdp {
+        private final String name;
+
+        private final Coder coder = new StandardCoder();
+        private final Queue<PdpStatus> replies = new LinkedList<>();
+
+        /**
+         * Messages that this PDP has handled.
+         */
+        @Getter
+        private final Queue<PdpMessage> handled = new ConcurrentLinkedQueue<>();
+
+        private volatile String group = null;
+        private volatile String subgroup = null;
+
+        private volatile boolean finished = true;
+
+        /**
+         * Constructs the object.
+         *
+         * @param name PDP name
+         */
+        private PseudoPdp(String name) {
+            this.name = name;
+        }
+
+        public PseudoPdp setGroup(String group) {
+            this.group = group;
+            return this;
+        }
+
+        public PseudoPdp setSubgroup(String subgroup) {
+            this.subgroup = subgroup;
+            return this;
+        }
+
+        /**
+         * Adds a reply to the list of replies that will be returned in response to
+         * messages from the PAP.
+         *
+         * @param reply reply to be added to the list
+         * @return this PDP
+         * @throws CoderException if the reply cannot be encoded
+         */
+        public PseudoPdp addReply(PdpStatus reply) throws CoderException {
+            replies.add(reply);
+            finished = false;
+            return this;
+        }
+
+        /**
+         * Handles an UPDATE message, recording the information extracted from the message
+         * and queuing up a reply, if any.
+         *
+         * @param message message that was received from PAP
+         */
+        private void handle(PdpUpdate message) {
+            if (message.appliesTo(name, group, subgroup)) {
+                handled.add(message);
+                group = message.getPdpGroup();
+                subgroup = message.getPdpSubgroup();
+                reply(message);
+            }
+        }
+
+        /**
+         * Handles a STAT-CHANGE message. Queues up a reply, if any.
+         *
+         * @param message message that was received from PAP
+         */
+        private void handle(PdpStateChange message) {
+            if (message.appliesTo(name, group, subgroup)) {
+                handled.add(message);
+                reply(message);
+            }
+        }
+
+        /**
+         * Queues up the next reply. If there are no more replies, then it queues up a
+         * {@link End2EndContext#DONE} message.
+         *
+         * @param message the message to which a reply should be sent
+         */
+        private void reply(PdpMessage message) {
+            PdpStatus status = replies.poll();
+            if (status == null) {
+                return;
+            }
+
+            PdpResponseDetails response = new PdpResponseDetails();
+            response.setResponseTo(message.getRequestId());
+            status.setResponse(response);
+
+            toPap.add(toJson(status));
+
+            if (replies.isEmpty()) {
+                finished = true;
+                toPap.add(DONE);
+            }
+        }
+
+        /**
+         * Converts a message to JSON.
+         *
+         * @param status message to be converted
+         * @return JSON representation of the message
+         */
+        private String toJson(PdpStatus status) {
+            try {
+                return coder.encode(status);
+
+            } catch (CoderException e) {
+                exception = e;
+                return DONE;
+            }
+        }
+
+        @Override
+        public String toString() {
+            return name;
+        }
+    }
+}
diff --git a/main/src/test/java/org/onap/policy/pap/main/rest/e2e/HealthCheckTest.java b/main/src/test/java/org/onap/policy/pap/main/rest/e2e/HealthCheckTest.java
new file mode 100644 (file)
index 0000000..f429afb
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP PAP
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.pap.main.rest.e2e;
+
+import static org.junit.Assert.assertEquals;
+
+import java.net.HttpURLConnection;
+import javax.ws.rs.client.Invocation;
+import org.junit.Test;
+import org.onap.policy.common.endpoints.report.HealthCheckReport;
+
+public class HealthCheckTest extends End2EndBase {
+    private static final String HEALTHCHECK_ENDPOINT = "healthcheck";
+
+    @Test
+    public void testHealthCheckSuccess() throws Exception {
+        final Invocation.Builder invocationBuilder = sendRequest(HEALTHCHECK_ENDPOINT);
+        final HealthCheckReport report = invocationBuilder.get(HealthCheckReport.class);
+
+        assertEquals(NAME, report.getName());
+        assertEquals(SELF, report.getUrl());
+        assertEquals(true, report.isHealthy());
+        assertEquals(HttpURLConnection.HTTP_OK, report.getCode());
+        assertEquals(ALIVE, report.getMessage());
+    }
+}
diff --git a/main/src/test/java/org/onap/policy/pap/main/rest/e2e/PdpGroupDeleteTest.java b/main/src/test/java/org/onap/policy/pap/main/rest/e2e/PdpGroupDeleteTest.java
new file mode 100644 (file)
index 0000000..9ffe103
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP PAP
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.pap.main.rest.e2e;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import java.util.Collections;
+import javax.ws.rs.client.Invocation;
+import javax.ws.rs.core.Response;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.onap.policy.models.pap.concepts.PdpGroupDeleteResponse;
+import org.onap.policy.models.pdp.concepts.PdpStatus;
+
+public class PdpGroupDeleteTest extends End2EndBase {
+    private static final String DELETE_GROUP_ENDPOINT = "pdps/groups";
+    private static final String DELETE_POLICIES_ENDPOINT = "pdps/policies";
+
+    /**
+     * Starts Main and adds policies to the DB.
+     *
+     * @throws Exception if an error occurs
+     */
+    @BeforeClass
+    public static void setUpBeforeClass() throws Exception {
+        End2EndBase.setUpBeforeClass();
+
+        addToscaPolicyTypes("monitoring.policy-type.yaml");
+        addToscaPolicies("monitoring.policy.yaml");
+    }
+
+    /**
+     * Sets up.
+     */
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+
+        context = new End2EndContext();
+    }
+
+    @Test
+    public void testDeleteGroup() throws Exception {
+        addGroups("deleteGroup.json");
+
+        context.addPdp("pdpAA_1", "pdpTypeA");
+        context.addPdp("pdpAA_2", "pdpTypeA");
+        context.addPdp("pdpAB_1", "pdpTypeB");
+
+        context.startThreads();
+
+        String uri = DELETE_GROUP_ENDPOINT + "/deleteGroup";
+
+        Invocation.Builder invocationBuilder = sendRequest(uri);
+        Response rawresp = invocationBuilder.delete();
+        PdpGroupDeleteResponse resp = rawresp.readEntity(PdpGroupDeleteResponse.class);
+        assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
+        assertNull(resp.getErrorDetails());
+
+        context.await();
+
+        // none of the PDPs should have handled any requests
+        assertEquals(context.getPdps().size(),
+                        context.getPdps().stream().filter(pdp -> pdp.getHandled().isEmpty()).count());
+
+        // repeat - should fail
+        rawresp = invocationBuilder.delete();
+        resp = rawresp.readEntity(PdpGroupDeleteResponse.class);
+        assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), rawresp.getStatus());
+        assertEquals("group not found", resp.getErrorDetails());
+    }
+
+    @Test
+    public void testDeletePolicy() throws Exception {
+        addGroups("undeployPolicy.json");
+
+        PdpStatus status1 = new PdpStatus();
+        status1.setName("pdpBA_1");
+        status1.setPdpGroup("undeployPolicy");
+        status1.setPdpSubgroup("pdpTypeA");
+        status1.setPolicies(Collections.emptyList());
+
+        PdpStatus status2 = new PdpStatus();
+        status2.setName("pdpBA_2");
+        status2.setPdpGroup("undeployPolicy");
+        status2.setPdpSubgroup("pdpTypeA");
+        status2.setPolicies(Collections.emptyList());
+
+        context.addPdp("pdpBA_1", "pdpTypeA").addReply(status1);
+        context.addPdp("pdpBA_2", "pdpTypeA").addReply(status2);
+        context.addPdp("pdpBB_1", "pdpTypeB");
+
+        context.startThreads();
+
+        String uri = DELETE_POLICIES_ENDPOINT + "/onap.restart.tcaB";
+
+        Invocation.Builder invocationBuilder = sendRequest(uri);
+        Response rawresp = invocationBuilder.delete();
+        PdpGroupDeleteResponse resp = rawresp.readEntity(PdpGroupDeleteResponse.class);
+        assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
+        assertNull(resp.getErrorDetails());
+
+        context.await();
+
+        rawresp = invocationBuilder.delete();
+        resp = rawresp.readEntity(PdpGroupDeleteResponse.class);
+        assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
+        assertNull(resp.getErrorDetails());
+    }
+
+    @Test
+    public void testDeletePolicyVersion() throws Exception {
+        addGroups("undeployPolicyVersion.json");
+
+        PdpStatus status1 = new PdpStatus();
+        status1.setName("pdpCA_1");
+        status1.setPdpGroup("undeployPolicyVersion");
+        status1.setPdpSubgroup("pdpTypeA");
+        status1.setPolicies(Collections.emptyList());
+
+        PdpStatus status2 = new PdpStatus();
+        status2.setName("pdpCA_2");
+        status2.setPdpGroup("undeployPolicyVersion");
+        status2.setPdpSubgroup("pdpTypeA");
+        status2.setPolicies(Collections.emptyList());
+
+        context.addPdp("pdpCA_1", "pdpTypeA").addReply(status1);
+        context.addPdp("pdpCA_2", "pdpTypeA").addReply(status2);
+        context.addPdp("pdpCB_1", "pdpTypeB");
+
+        context.startThreads();
+
+        String uri = DELETE_POLICIES_ENDPOINT + "/onap.restart.tcaC/versions/1.0.0";
+
+        Invocation.Builder invocationBuilder = sendRequest(uri);
+        Response rawresp = invocationBuilder.delete();
+        PdpGroupDeleteResponse resp = rawresp.readEntity(PdpGroupDeleteResponse.class);
+        assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
+        assertNull(resp.getErrorDetails());
+
+        context.await();
+
+        rawresp = invocationBuilder.delete();
+        resp = rawresp.readEntity(PdpGroupDeleteResponse.class);
+        assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
+        assertNull(resp.getErrorDetails());
+    }
+}
diff --git a/main/src/test/java/org/onap/policy/pap/main/rest/e2e/PdpGroupDeployTest.java b/main/src/test/java/org/onap/policy/pap/main/rest/e2e/PdpGroupDeployTest.java
new file mode 100644 (file)
index 0000000..5279236
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP PAP
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.pap.main.rest.e2e;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.List;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.Invocation;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.onap.policy.models.pap.concepts.PdpDeployPolicies;
+import org.onap.policy.models.pap.concepts.PdpGroupDeployResponse;
+import org.onap.policy.models.pdp.concepts.PdpGroups;
+import org.onap.policy.models.pdp.concepts.PdpStatus;
+import org.onap.policy.models.pdp.enums.PdpState;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PdpGroupDeployTest extends End2EndBase {
+    private static final Logger logger = LoggerFactory.getLogger(PdpGroupDeployTest.class);
+
+    private static final String DEPLOY_GROUP_ENDPOINT = "pdps";
+    private static final String DEPLOY_POLICIES_ENDPOINT = "pdps/policies";
+    private static final String DELETE_GROUP_ENDPOINT = "pdps/groups";
+    private static final String CREATE_SUBGROUP = "pdpTypeA";
+    private static final String DEPLOY_SUBGROUP = "pdpTypeA";
+
+    /**
+     * Starts Main and adds policies to the DB.
+     *
+     * @throws Exception if an error occurs
+     */
+    @BeforeClass
+    public static void setUpBeforeClass() throws Exception {
+        End2EndBase.setUpBeforeClass();
+
+        addToscaPolicyTypes("monitoring.policy-type.yaml");
+        addToscaPolicies("monitoring.policy.yaml");
+    }
+
+    /**
+     * Sets up.
+     */
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+
+        context = new End2EndContext();
+    }
+
+    /**
+     * Deletes the deployed group.
+     */
+    @After
+    public void tearDown() {
+        // delete the group that was inserted
+        try {
+            sendRequest(DELETE_GROUP_ENDPOINT + "/createGroups").delete();
+        } catch (Exception e) {
+            logger.warn("cannot delete group: createGroups", e);
+        }
+
+        super.tearDown();
+    }
+
+    @Test
+    public void testCreateGroups() throws Exception {
+
+        context.addPdp("pdpAA_1", CREATE_SUBGROUP);
+        context.addPdp("pdpAA_2", CREATE_SUBGROUP);
+        context.addPdp("pdpAB_1", "pdpTypeB");
+
+        context.startThreads();
+
+        Invocation.Builder invocationBuilder = sendRequest(DEPLOY_GROUP_ENDPOINT);
+
+        PdpGroups groups = loadJsonFile("createGroups.json", PdpGroups.class);
+        Entity<PdpGroups> entity = Entity.entity(groups, MediaType.APPLICATION_JSON);
+        Response rawresp = invocationBuilder.post(entity);
+        PdpGroupDeployResponse resp = rawresp.readEntity(PdpGroupDeployResponse.class);
+        assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
+        assertNull(resp.getErrorDetails());
+
+        context.await();
+
+        // none of the PDPs should have handled any requests
+        assertEquals(context.getPdps().size(),
+                        context.getPdps().stream().filter(pdp -> pdp.getHandled().isEmpty()).count());
+
+        // repeat - should be OK
+        rawresp = invocationBuilder.post(entity);
+        resp = rawresp.readEntity(PdpGroupDeployResponse.class);
+        assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
+        assertNull(resp.getErrorDetails());
+
+        // repeat with different properties - should fail
+        groups.getGroups().get(0).setProperties(null);
+        rawresp = invocationBuilder.post(entity);
+        resp = rawresp.readEntity(PdpGroupDeployResponse.class);
+        assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), rawresp.getStatus());
+        assertTrue(resp.getErrorDetails().contains("cannot change properties"));
+    }
+
+    @Test
+    public void testDeployPolicies() throws Exception {
+        addGroups("deployPolicies.json");
+
+        PdpStatus status11 = new PdpStatus();
+        status11.setName("pdpBA_1");
+        status11.setState(PdpState.ACTIVE);
+        status11.setPdpGroup("deployPolicies");
+        status11.setPdpType(DEPLOY_SUBGROUP);
+        status11.setPdpSubgroup(DEPLOY_SUBGROUP);
+
+        List<ToscaPolicyIdentifier> idents = Arrays.asList(new ToscaPolicyIdentifier("onap.restart.tca", "1.0.0"));
+        status11.setPolicies(idents);
+
+        PdpStatus status12 = new PdpStatus();
+        status12.setName("pdpBA_2");
+        status12.setState(PdpState.ACTIVE);
+        status12.setPdpGroup("deployPolicies");
+        status12.setPdpType(DEPLOY_SUBGROUP);
+        status12.setPdpSubgroup(DEPLOY_SUBGROUP);
+        status12.setPolicies(idents);
+
+        context.addPdp("pdpBA_1", DEPLOY_SUBGROUP).addReply(status11);
+        context.addPdp("pdpBA_2", DEPLOY_SUBGROUP).addReply(status12);
+        context.addPdp("pdpBB_1", "pdpTypeB");
+
+        context.startThreads();
+
+        Invocation.Builder invocationBuilder = sendRequest(DEPLOY_POLICIES_ENDPOINT);
+
+        PdpDeployPolicies policies = loadJsonFile("deployPoliciesReq.json", PdpDeployPolicies.class);
+        Entity<PdpDeployPolicies> entity = Entity.entity(policies, MediaType.APPLICATION_JSON);
+        Response rawresp = invocationBuilder.post(entity);
+        PdpGroupDeployResponse resp = rawresp.readEntity(PdpGroupDeployResponse.class);
+        System.out.println(resp.getErrorDetails());
+        assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
+        assertNull(resp.getErrorDetails());
+
+        context.await();
+
+        // one of the PDPs should not have handled any requests
+        assertEquals(1, context.getPdps().stream().filter(pdp -> pdp.getHandled().isEmpty()).count());
+
+        // repeat - should be OK
+        rawresp = invocationBuilder.post(entity);
+        resp = rawresp.readEntity(PdpGroupDeployResponse.class);
+        assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
+        assertNull(resp.getErrorDetails());
+    }
+}
diff --git a/main/src/test/java/org/onap/policy/pap/main/rest/e2e/PdpGroupQueryTest.java b/main/src/test/java/org/onap/policy/pap/main/rest/e2e/PdpGroupQueryTest.java
new file mode 100644 (file)
index 0000000..5f16751
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP PAP
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.pap.main.rest.e2e;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+import javax.ws.rs.client.Invocation;
+import javax.ws.rs.core.Response;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.onap.policy.models.pdp.concepts.Pdp;
+import org.onap.policy.models.pdp.concepts.PdpGroup;
+import org.onap.policy.models.pdp.concepts.PdpGroups;
+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.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier;
+
+public class PdpGroupQueryTest extends End2EndBase {
+    private static final String GROUP_ENDPOINT = "pdps";
+
+    /**
+     * Starts Main and adds policies to the DB.
+     *
+     * @throws Exception if an error occurs
+     */
+    @BeforeClass
+    public static void setUpBeforeClass() throws Exception {
+        End2EndBase.setUpBeforeClass();
+
+        addToscaPolicyTypes("monitoring.policy-type.yaml");
+        addToscaPolicies("monitoring.policy.yaml");
+
+        addGroups("queryGroup.json");
+    }
+
+    @Test
+    public void test() throws Exception {
+        Invocation.Builder invocationBuilder = sendRequest(GROUP_ENDPOINT);
+        Response rawresp = invocationBuilder.get();
+        PdpGroups resp = rawresp.readEntity(PdpGroups.class);
+        assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
+
+        assertEquals("[queryGroup1, queryGroup2]", mapList(resp.getGroups(), PdpGroup::getName).toString());
+
+        checkGroup1(resp.getGroups().get(0));
+        checkGroup2(resp.getGroups().get(1));
+    }
+
+    private void checkGroup1(PdpGroup group) {
+        assertEquals("[pdpTypeA, pdpTypeB]", mapList(group.getPdpSubgroups(), PdpSubGroup::getPdpType).toString());
+
+        assertEquals("my description", group.getDescription());
+        assertEquals(PdpState.PASSIVE, group.getPdpGroupState());
+
+        Map<String, Object> props = new LinkedHashMap<>();
+        props.put("abc", "def");
+        assertEquals(props.toString(), group.getProperties().toString());
+
+        checkSubGroup11(group.getPdpSubgroups().get(0));
+    }
+
+    private void checkSubGroup11(PdpSubGroup subgrp) {
+        assertEquals(3, subgrp.getCurrentInstanceCount());
+        assertEquals(2, subgrp.getDesiredInstanceCount());
+        assertEquals("[pdpAA_1, pdpAA_2]", mapList(subgrp.getPdpInstances(), Pdp::getInstanceId).toString());
+        assertEquals(2, filterList(subgrp.getPdpInstances(), pdp -> pdp.getPdpState() == PdpState.PASSIVE).size());
+        assertEquals(2, filterList(subgrp.getPdpInstances(), pdp -> pdp.getHealthy() == PdpHealthStatus.HEALTHY)
+                        .size());
+        assertEquals("pdpTypeA", subgrp.getPdpType());
+        assertEquals("[onap.restart.tca]", mapList(subgrp.getPolicies(), ToscaPolicyIdentifier::getName).toString());
+        assertEquals("[1.0.0]", mapList(subgrp.getPolicies(), ToscaPolicyIdentifier::getVersion).toString());
+
+        Map<String, Object> props = new LinkedHashMap<>();
+        props.put("ten", 10);
+        assertEquals(props.toString(), subgrp.getProperties().toString());
+
+        assertEquals("[onap.policies.monitoring.cdap.tca.hi.lo.app]",
+                        mapList(subgrp.getSupportedPolicyTypes(), ToscaPolicyTypeIdentifier::getName).toString());
+        assertEquals("[1.0.0]",
+                        mapList(subgrp.getSupportedPolicyTypes(), ToscaPolicyTypeIdentifier::getVersion).toString());
+    }
+
+    private void checkGroup2(PdpGroup group) {
+        assertEquals("[pdpTypeA]", mapList(group.getPdpSubgroups(), PdpSubGroup::getPdpType).toString());
+
+        assertEquals(PdpState.ACTIVE, group.getPdpGroupState());
+        assertTrue(group.getProperties() == null || group.getProperties().isEmpty());
+    }
+
+    private <T, R> List<R> mapList(List<T> list, Function<T, R> mapFunc) {
+        return list.stream().map(mapFunc).collect(Collectors.toList());
+    }
+
+    private <T> List<T> filterList(List<T> list, Predicate<T> pred) {
+        return list.stream().filter(pred).collect(Collectors.toList());
+    }
+}
diff --git a/main/src/test/java/org/onap/policy/pap/main/rest/e2e/PdpGroupStateChangeTest.java b/main/src/test/java/org/onap/policy/pap/main/rest/e2e/PdpGroupStateChangeTest.java
new file mode 100644 (file)
index 0000000..6fdd516
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP PAP
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.pap.main.rest.e2e;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import java.util.Collections;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.Invocation;
+import javax.ws.rs.core.Response;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.onap.policy.models.pap.concepts.PdpGroupStateChangeResponse;
+import org.onap.policy.models.pdp.concepts.PdpStatus;
+import org.onap.policy.models.pdp.enums.PdpState;
+
+public class PdpGroupStateChangeTest extends End2EndBase {
+    private static final String PDP1 = "pdpAA_1";
+    private static final String PDP2 = "pdpAA_2";
+    private static final String PDP3 = "pdpAB_1";
+    private static final String SUBGROUP1 = "pdpTypeA";
+    private static final String SUBGROUP2 = "pdpTypeB";
+    private static final String DEACT_GROUP = "stateChangeGroupDeactivate";
+    private static final String GROUP_ENDPOINT = "pdps/groups";
+
+    /**
+     * Starts Main and adds policies to the DB.
+     *
+     * @throws Exception if an error occurs
+     */
+    @BeforeClass
+    public static void setUpBeforeClass() throws Exception {
+        End2EndBase.setUpBeforeClass();
+
+        addToscaPolicyTypes("monitoring.policy-type.yaml");
+        addToscaPolicies("monitoring.policy.yaml");
+    }
+
+    /**
+     * Sets up.
+     */
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+
+        context = new End2EndContext();
+    }
+
+    @Test
+    public void testMakePassive() throws Exception {
+        addGroups("stateChangeGroupDeactivate.json");
+
+        PdpStatus status11 = new PdpStatus();
+        status11.setName(PDP1);
+        status11.setState(PdpState.ACTIVE);
+        status11.setPdpGroup(DEACT_GROUP);
+        status11.setPdpType(SUBGROUP1);
+        status11.setPdpSubgroup(SUBGROUP1);
+        status11.setPolicies(Collections.emptyList());
+
+        PdpStatus status12 = makeCopy(status11);
+        status12.setState(PdpState.PASSIVE);
+
+        PdpStatus status21 = new PdpStatus();
+        status21.setName(PDP2);
+        status21.setState(PdpState.ACTIVE);
+        status21.setPdpGroup(DEACT_GROUP);
+        status21.setPdpType(SUBGROUP1);
+        status21.setPdpSubgroup(SUBGROUP1);
+        status21.setPolicies(Collections.emptyList());
+
+        PdpStatus status22 = makeCopy(status21);
+        status22.setState(PdpState.PASSIVE);
+
+        PdpStatus status31 = new PdpStatus();
+        status31.setName(PDP3);
+        status31.setState(PdpState.ACTIVE);
+        status31.setPdpGroup(DEACT_GROUP);
+        status31.setPdpType(SUBGROUP2);
+        status31.setPdpSubgroup(SUBGROUP2);
+        status31.setPolicies(Collections.emptyList());
+
+        PdpStatus status32 = makeCopy(status31);
+        status32.setState(PdpState.PASSIVE);
+
+        context.addPdp(PDP1, SUBGROUP1).addReply(status11).addReply(status12);
+        context.addPdp(PDP2, SUBGROUP1).addReply(status21).addReply(status22);
+        context.addPdp(PDP3, SUBGROUP2).addReply(status31).addReply(status32);
+
+        context.startThreads();
+
+        String uri = GROUP_ENDPOINT + "/" + DEACT_GROUP + "?state=PASSIVE";
+
+        Invocation.Builder invocationBuilder = sendRequest(uri);
+        Response rawresp = invocationBuilder.put(Entity.json(""));
+        PdpGroupStateChangeResponse resp = rawresp.readEntity(PdpGroupStateChangeResponse.class);
+        assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
+        assertNull(resp.getErrorDetails());
+
+        context.await();
+    }
+
+    private PdpStatus makeCopy(PdpStatus source) {
+        PdpStatus status = new PdpStatus();
+
+        status.setHealthy(source.getHealthy());
+        status.setName(source.getName());
+        status.setPdpGroup(source.getPdpGroup());
+        status.setPdpSubgroup(source.getPdpSubgroup());
+        status.setPdpType(source.getPdpType());
+        status.setPolicies(source.getPolicies());
+
+        return status;
+    }
+}
diff --git a/main/src/test/java/org/onap/policy/pap/main/rest/e2e/StatisticsTest.java b/main/src/test/java/org/onap/policy/pap/main/rest/e2e/StatisticsTest.java
new file mode 100644 (file)
index 0000000..13492cf
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP PAP
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.pap.main.rest.e2e;
+
+import static org.junit.Assert.assertEquals;
+
+import java.net.HttpURLConnection;
+import javax.ws.rs.client.Invocation;
+import org.junit.Test;
+import org.onap.policy.common.utils.services.Registry;
+import org.onap.policy.pap.main.PapConstants;
+import org.onap.policy.pap.main.rest.PapStatisticsManager;
+import org.onap.policy.pap.main.rest.StatisticsReport;
+
+public class StatisticsTest extends End2EndBase {
+    private static final String STATISTICS_ENDPOINT = "statistics";
+
+
+    @Test
+    public void test() throws Exception {
+        Invocation.Builder invocationBuilder = sendRequest(STATISTICS_ENDPOINT);
+        StatisticsReport report = invocationBuilder.get(StatisticsReport.class);
+        assertEquals(HttpURLConnection.HTTP_OK, report.getCode());
+
+        updateDistributionStatistics();
+
+        invocationBuilder = sendRequest(STATISTICS_ENDPOINT);
+        StatisticsReport report2 = invocationBuilder.get(StatisticsReport.class);
+
+        assertEquals(HttpURLConnection.HTTP_OK, report.getCode());
+        assertEquals(report.getTotalPdpCount() + 1, report2.getTotalPdpCount());
+        assertEquals(report.getTotalPdpGroupCount() + 1, report2.getTotalPdpGroupCount());
+        assertEquals(report.getTotalPolicyDeployCount() + 1, report2.getTotalPolicyDeployCount());
+        assertEquals(report.getPolicyDeploySuccessCount() + 1, report2.getPolicyDeploySuccessCount());
+        assertEquals(report.getPolicyDeployFailureCount() + 1, report2.getPolicyDeployFailureCount());
+        assertEquals(report.getTotalPolicyDownloadCount() + 1, report2.getTotalPolicyDownloadCount());
+        assertEquals(report.getPolicyDeploySuccessCount() + 1, report2.getPolicyDeploySuccessCount());
+        assertEquals(report.getPolicyDeployFailureCount() + 1, report2.getPolicyDeployFailureCount());
+    }
+
+    private void updateDistributionStatistics() {
+        PapStatisticsManager mgr = Registry.get(PapConstants.REG_STATISTICS_MANAGER, PapStatisticsManager.class);
+
+        mgr.updateTotalPdpCount();
+        mgr.updateTotalPdpGroupCount();
+        mgr.updateTotalPolicyDeployCount();
+        mgr.updatePolicyDeploySuccessCount();
+        mgr.updatePolicyDeployFailureCount();
+        mgr.updateTotalPolicyDownloadCount();
+        mgr.updatePolicyDownloadSuccessCount();
+        mgr.updatePolicyDownloadFailureCount();
+    }
+}
diff --git a/main/src/test/resources/e2e/PapConfigParameters.json b/main/src/test/resources/e2e/PapConfigParameters.json
new file mode 100644 (file)
index 0000000..4e085f7
--- /dev/null
@@ -0,0 +1,29 @@
+{
+    "name": "PapGroup",
+    "restServerParameters": {
+        "host": "0.0.0.0",
+        "port": ${port},
+        "userName": "healthcheck",
+        "password": "zb!XztG34",
+        "https": true
+    },
+    "pdpParameters": {
+        "updateParameters": {
+            "maxRetryCount": 0,
+            "maxWaitMs": 5000
+        },
+        "stateChangeParameters": {
+            "maxRetryCount": 0,
+            "maxWaitMs": 5000
+        }
+    },
+    "databaseProviderParameters": {
+        "name": "PolicyModelsProviderParameters",
+        "implementation": "org.onap.policy.models.provider.impl.DatabasePolicyModelsProviderImpl",
+        "databaseDriver": "org.h2.Driver",
+        "databaseUrl": "${dbName}",
+        "databaseUser": "policy",
+        "databasePassword": "UDAxaWNZ",
+        "persistenceUnit": "ToscaConceptTest"
+    }
+}
diff --git a/main/src/test/resources/e2e/createGroups.json b/main/src/test/resources/e2e/createGroups.json
new file mode 100644 (file)
index 0000000..1c8774b
--- /dev/null
@@ -0,0 +1,61 @@
+{
+    "groups": [
+        {
+            "name": "createGroups",
+            "pdpGroupState": "PASSIVE",
+            "properties": {
+                "hello": "world"
+            },
+            "pdpSubgroups": [
+                {
+                    "pdpType": "pdpTypeA",
+                    "desiredInstanceCount": 2,
+                    "properties": {},
+                    "pdpInstances": [
+                        {
+                            "instanceId": "pdpAA_1",
+                            "pdpState": "ACTIVE",
+                            "healthy": "HEALTHY"
+                        },
+                        {
+                            "instanceId": "pdpAA_2",
+                            "pdpState": "ACTIVE",
+                            "healthy": "HEALTHY"
+                        }
+                    ],
+                    "supportedPolicyTypes": [
+                        {
+                            "name": "onap.policies.monitoring.cdap.tca.hi.lo.app",
+                            "version": "1.0.0"
+                        }
+                    ],
+                    "policies": [
+                        {
+                            "name": "onap.restart.tca",
+                            "version": "1.0.0"
+                        }
+                    ]
+                },
+                {
+                    "pdpType": "pdpTypeB",
+                    "desiredInstanceCount": 1,
+                    "properties": {},
+                    "pdpInstances": [
+                        {
+                            "instanceId": "pdpAB_1",
+                            "pdpState": "ACTIVE",
+                            "healthy": "HEALTHY"
+                        }
+                    ],
+                    "supportedPolicyTypes": [
+                        {
+                            "name": "onap.policies.monitoring.cdap.tca.hi.lo.app",
+                            "version": "1.0.0"
+                        }
+                    ],
+                    "policies": []
+                }
+            ]
+        }
+    ]
+}
diff --git a/main/src/test/resources/e2e/deleteGroup.json b/main/src/test/resources/e2e/deleteGroup.json
new file mode 100644 (file)
index 0000000..4351d5c
--- /dev/null
@@ -0,0 +1,56 @@
+{
+    "groups": [
+        {
+            "name": "deleteGroup",
+            "pdpGroupState": "PASSIVE",
+            "pdpSubgroups": [
+                {
+                    "pdpType": "pdpTypeA",
+                    "desiredInstanceCount": 2,
+                    "pdpInstances": [
+                        {
+                            "instanceId": "pdpAA_1",
+                            "pdpState": "PASSIVE",
+                            "healthy": "HEALTHY"
+                        },
+                        {
+                            "instanceId": "pdpAA_2",
+                            "pdpState": "PASSIVE",
+                            "healthy": "HEALTHY"
+                        }
+                    ],
+                    "supportedPolicyTypes": [
+                        {
+                            "name": "onap.policies.monitoring.cdap.tca.hi.lo.app",
+                            "version": "1.0.0"
+                        }
+                    ],
+                    "policies": [
+                        {
+                            "name": "onap.restart.tca",
+                            "version": "1.0.0"
+                        }
+                    ]
+                },
+                {
+                    "pdpType": "pdpTypeB",
+                    "desiredInstanceCount": 1,
+                    "pdpInstances": [
+                        {
+                            "instanceId": "pdpAB_1",
+                            "pdpState": "PASSIVE",
+                            "healthy": "HEALTHY"
+                        }
+                    ],
+                    "supportedPolicyTypes": [
+                        {
+                            "name": "onap.policies.monitoring.cdap.tca.hi.lo.app",
+                            "version": "1.0.0"
+                        }
+                    ],
+                    "policies": []
+                }
+            ]
+        }
+    ]
+}
diff --git a/main/src/test/resources/e2e/deployPolicies.json b/main/src/test/resources/e2e/deployPolicies.json
new file mode 100644 (file)
index 0000000..4cafe77
--- /dev/null
@@ -0,0 +1,56 @@
+{
+    "groups": [
+        {
+            "name": "deployPolicies",
+            "pdpGroupState": "ACTIVE",
+            "pdpSubgroups": [
+                {
+                    "pdpType": "pdpTypeA",
+                    "desiredInstanceCount": 2,
+                    "pdpInstances": [
+                        {
+                            "instanceId": "pdpBA_1",
+                            "pdpState": "ACTIVE",
+                            "healthy": "HEALTHY"
+                        },
+                        {
+                            "instanceId": "pdpBA_2",
+                            "pdpState": "ACTIVE",
+                            "healthy": "HEALTHY"
+                        }
+                    ],
+                    "supportedPolicyTypes": [
+                        {
+                            "name": "onap.policies.monitoring.cdap.tca.hi.lo.app",
+                            "version": "1.0.0"
+                        }
+                    ],
+                    "policies": []
+                },
+                {
+                    "pdpType": "pdpTypeB",
+                    "desiredInstanceCount": 1,
+                    "pdpInstances": [
+                        {
+                            "instanceId": "pdpBB_1",
+                            "pdpState": "ACTIVE",
+                            "healthy": "HEALTHY"
+                        }
+                    ],
+                    "supportedPolicyTypes": [
+                        {
+                            "name": "onap.policies.monitoring.cdap.tca.hi.lo.app",
+                            "version": "1.0.0"
+                        }
+                    ],
+                    "policies": [
+                        {
+                            "name": "onap.restart.tca",
+                            "version": "1.0.0"
+                        }
+                    ]
+                }
+            ]
+        }
+    ]
+}
diff --git a/main/src/test/resources/e2e/deployPoliciesReq.json b/main/src/test/resources/e2e/deployPoliciesReq.json
new file mode 100644 (file)
index 0000000..c613951
--- /dev/null
@@ -0,0 +1,7 @@
+{
+    "policies": [
+        {
+            "policy-id": "onap.restart.tca"
+        }
+    ]
+}
\ No newline at end of file
diff --git a/main/src/test/resources/e2e/monitoring.policy-type.yaml b/main/src/test/resources/e2e/monitoring.policy-type.yaml
new file mode 100644 (file)
index 0000000..98b6452
--- /dev/null
@@ -0,0 +1,164 @@
+tosca_definitions_version: tosca_simple_yaml_1_0_0
+policy_types:
+  -
+    onap.policies.Monitoring:
+        derived_from: tosca.policies.Root
+        description: a base policy type for all policies that governs monitoring provisioning
+        version: 1.0.0
+  -
+    onap.policy.monitoring.cdap.tca.hi.lo.app:
+        derived_from: onap.policies.Monitoring
+        version: 1.0.0
+        properties:
+            tca_policy:
+                type: map
+                description: TCA Policy JSON
+                entry_schema:
+                    type: onap.datatypes.monitoring.tca_policy
+data_types:
+  -
+    onap.datatypes.monitoring.metricsPerEventName:
+        derived_from: tosca.datatypes.Root
+        properties:
+            controlLoopSchemaType:
+                type: string
+                required: true
+                description: Specifies Control Loop Schema Type for the event Name e.g. VNF, VM
+                constraints:
+                  - valid_values:
+                      - VM
+                      - VNF
+            eventName:
+                type: string
+                required: true
+                description: Event name to which thresholds need to be applied
+            policyName:
+                type: string
+                required: true
+                description: TCA Policy Scope Name
+            policyScope:
+                type: string
+                required: true
+                description: TCA Policy Scope
+            policyVersion:
+                type: string
+                required: true
+                description: TCA Policy Scope Version
+            thresholds:
+                type: list
+                required: true
+                description: Thresholds associated with eventName
+                entry_schema:
+                    type: onap.datatypes.monitoring.thresholds
+  -
+    onap.datatypes.monitoring.tca_policy:
+        derived_from: tosca.datatypes.Root
+        properties:
+            domain:
+                type: string
+                required: true
+                description: Domain name to which TCA needs to be applied
+                default: measurementsForVfScaling
+                constraints:
+                  - equal: measurementsForVfScaling
+            metricsPerEventName:
+                type: list
+                required: true
+                description: Contains eventName and threshold details that need to be applied to given eventName
+                entry_schema:
+                    type: onap.datatypes.monitoring.metricsPerEventName
+  -
+    onap.datatypes.monitoring.thresholds:
+        derived_from: tosca.datatypes.Root
+        properties:
+            closedLoopControlName:
+                type: string
+                required: true
+                description: Closed Loop Control Name associated with the threshold
+            closedLoopEventStatus:
+                type: string
+                required: true
+                description: Closed Loop Event Status of the threshold
+                constraints:
+                  - valid_values:
+                      - ONSET
+                      - ABATED
+            direction:
+                type: string
+                required: true
+                description: Direction of the threshold
+                constraints:
+                  - valid_values:
+                      - LESS
+                      - LESS_OR_EQUAL
+                      - GREATER
+                      - GREATER_OR_EQUAL
+                      - EQUAL
+            fieldPath:
+                type: string
+                required: true
+                description: Json field Path as per CEF message which needs to be analyzed for TCA
+                constraints:
+                  - valid_values:
+                      - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedTotalPacketsDelta
+                      - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedOctetsDelta
+                      - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedUnicastPacketsDelta
+                      - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedMulticastPacketsDelta
+                      - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedBroadcastPacketsDelta
+                      - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedDiscardedPacketsDelta
+                      - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedErrorPacketsDelta
+                      - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedTotalPacketsAccumulated
+                      - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedOctetsAccumulated
+                      - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedUnicastPacketsAccumulated
+                      - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedMulticastPacketsAccumulated
+                      - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedBroadcastPacketsAccumulated
+                      - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedDiscardedPacketsAccumulated
+                      - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedErrorPacketsAccumulated
+                      - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].transmittedTotalPacketsDelta
+                      - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].transmittedOctetsDelta
+                      - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].transmittedUnicastPacketsDelta
+                      - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].transmittedMulticastPacketsDelta
+                      - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].transmittedBroadcastPacketsDelta
+                      - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].transmittedDiscardedPacketsDelta
+                      - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].transmittedErrorPacketsDelta
+                      - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].transmittedTotalPacketsAccumulated
+                      - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].transmittedOctetsAccumulated
+                      - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].transmittedUnicastPacketsAccumulated
+                      - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].transmittedMulticastPacketsAccumulated
+                      - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].transmittedBroadcastPacketsAccumulated
+                      - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].transmittedDiscardedPacketsAccumulated
+                      - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].transmittedErrorPacketsAccumulated
+                      - $.event.measurementsForVfScalingFields.cpuUsageArray[*].cpuIdle
+                      - $.event.measurementsForVfScalingFields.cpuUsageArray[*].cpuUsageInterrupt
+                      - $.event.measurementsForVfScalingFields.cpuUsageArray[*].cpuUsageNice
+                      - $.event.measurementsForVfScalingFields.cpuUsageArray[*].cpuUsageSoftIrq
+                      - $.event.measurementsForVfScalingFields.cpuUsageArray[*].cpuUsageSteal
+                      - $.event.measurementsForVfScalingFields.cpuUsageArray[*].cpuUsageSystem
+                      - $.event.measurementsForVfScalingFields.cpuUsageArray[*].cpuWait
+                      - $.event.measurementsForVfScalingFields.cpuUsageArray[*].percentUsage
+                      - $.event.measurementsForVfScalingFields.meanRequestLatency
+                      - $.event.measurementsForVfScalingFields.memoryUsageArray[*].memoryBuffered
+                      - $.event.measurementsForVfScalingFields.memoryUsageArray[*].memoryCached
+                      - $.event.measurementsForVfScalingFields.memoryUsageArray[*].memoryConfigured
+                      - $.event.measurementsForVfScalingFields.memoryUsageArray[*].memoryFree
+                      - $.event.measurementsForVfScalingFields.memoryUsageArray[*].memoryUsed
+                      - $.event.measurementsForVfScalingFields.additionalMeasurements[*].arrayOfFields[0].value
+            severity:
+                type: string
+                required: true
+                description: Threshold Event Severity
+                constraints:
+                  - valid_values:
+                      - CRITICAL
+                      - MAJOR
+                      - MINOR
+                      - WARNING
+                      - NORMAL
+            thresholdValue:
+                type: integer
+                required: true
+                description: Threshold value for the field Path inside CEF message
+            version:
+                type: string
+                required: true
+                description: Version number associated with the threshold
\ No newline at end of file
diff --git a/main/src/test/resources/e2e/monitoring.policy.yaml b/main/src/test/resources/e2e/monitoring.policy.yaml
new file mode 100644 (file)
index 0000000..fe15b47
--- /dev/null
@@ -0,0 +1,105 @@
+tosca_definitions_version: tosca_simple_yaml_1_0_0
+topology_template:
+   policies:
+     -
+       onap.restart.tca:
+           type: onap.policies.monitoring.cdap.tca.hi.lo.app
+           type_version: 1.0.0
+           version: 1.0.0
+           metadata:
+             policy-id: onap.restart.tca
+           properties:
+             tca_policy:
+                domain: measurementsForVfScaling
+                metricsPerEventName:
+                  -
+                    eventName: Measurement_vGMUX
+                    controlLoopSchemaType: VNF
+                    policyScope: DCAE
+                    policyName: "DCAE.Config_tca-hi-lo"
+                    policyVersion: "v0.0.1"
+                    thresholds:
+                      -
+                        closedLoopControlName: "ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e"
+                        version: "1.0.2"
+                        fieldPath: "$.event.measurementsForVfScalingFields.additionalMeasurements[*].arrayOfFields[0].value"
+                        thresholdValue: 0
+                        direction: EQUAL
+                        severity: MAJOR
+                        closedLoopEventStatus: ABATED
+                      -
+                        closedLoopControlName: "ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e"
+                        version: "1.0.2"
+                        fieldPath: "$.event.measurementsForVfScalingFields.additionalMeasurements[*].arrayOfFields[0].value"
+                        thresholdValue: 0
+                        direction: GREATER
+                        severity: CRITICAL
+                        closedLoopEventStatus: ONSET
+     -
+       onap.restart.tcaB:
+           type: onap.policies.monitoring.cdap.tca.hi.lo.app
+           type_version: 1.0.0
+           version: 1.0.0
+           metadata:
+             policy-id: onap.restart.tca
+           properties:
+             tca_policy:
+                domain: measurementsForVfScaling
+                metricsPerEventName:
+                  -
+                    eventName: Measurement_vGMUX
+                    controlLoopSchemaType: VNF
+                    policyScope: DCAE
+                    policyName: "DCAE.Config_tca-hi-lo"
+                    policyVersion: "v0.0.1"
+                    thresholds:
+                      -
+                        closedLoopControlName: "ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e"
+                        version: "1.0.2"
+                        fieldPath: "$.event.measurementsForVfScalingFields.additionalMeasurements[*].arrayOfFields[0].value"
+                        thresholdValue: 0
+                        direction: EQUAL
+                        severity: MAJOR
+                        closedLoopEventStatus: ABATED
+                      -
+                        closedLoopControlName: "ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e"
+                        version: "1.0.2"
+                        fieldPath: "$.event.measurementsForVfScalingFields.additionalMeasurements[*].arrayOfFields[0].value"
+                        thresholdValue: 0
+                        direction: GREATER
+                        severity: CRITICAL
+                        closedLoopEventStatus: ONSET
+     -
+       onap.restart.tcaC:
+           type: onap.policies.monitoring.cdap.tca.hi.lo.app
+           type_version: 1.0.0
+           version: 1.0.0
+           metadata:
+             policy-id: onap.restart.tca
+           properties:
+             tca_policy:
+                domain: measurementsForVfScaling
+                metricsPerEventName:
+                  -
+                    eventName: Measurement_vGMUX
+                    controlLoopSchemaType: VNF
+                    policyScope: DCAE
+                    policyName: "DCAE.Config_tca-hi-lo"
+                    policyVersion: "v0.0.1"
+                    thresholds:
+                      -
+                        closedLoopControlName: "ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e"
+                        version: "1.0.2"
+                        fieldPath: "$.event.measurementsForVfScalingFields.additionalMeasurements[*].arrayOfFields[0].value"
+                        thresholdValue: 0
+                        direction: EQUAL
+                        severity: MAJOR
+                        closedLoopEventStatus: ABATED
+                      -
+                        closedLoopControlName: "ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e"
+                        version: "1.0.2"
+                        fieldPath: "$.event.measurementsForVfScalingFields.additionalMeasurements[*].arrayOfFields[0].value"
+                        thresholdValue: 0
+                        direction: GREATER
+                        severity: CRITICAL
+                        closedLoopEventStatus: ONSET
diff --git a/main/src/test/resources/e2e/queryGroup.json b/main/src/test/resources/e2e/queryGroup.json
new file mode 100644 (file)
index 0000000..2a7b4ed
--- /dev/null
@@ -0,0 +1,98 @@
+{
+    "groups": [
+        {
+            "name": "queryGroup1",
+            "description": "my description",
+            "pdpGroupState": "PASSIVE",
+            "properties": {
+                    "abc": "def"
+                },
+            "pdpSubgroups": [
+                {
+                    "pdpType": "pdpTypeA",
+                    "currentInstanceCount": 3,
+                    "desiredInstanceCount": 2,
+                    "properties": {
+                            "ten": 10
+                        },
+                    "pdpInstances": [
+                        {
+                            "instanceId": "pdpAA_1",
+                            "pdpState": "PASSIVE",
+                            "healthy": "HEALTHY"
+                        },
+                        {
+                            "instanceId": "pdpAA_2",
+                            "pdpState": "PASSIVE",
+                            "healthy": "HEALTHY"
+                        }
+                    ],
+                    "supportedPolicyTypes": [
+                        {
+                            "name": "onap.policies.monitoring.cdap.tca.hi.lo.app",
+                            "version": "1.0.0"
+                        }
+                    ],
+                    "policies": [
+                        {
+                            "name": "onap.restart.tca",
+                            "version": "1.0.0"
+                        }
+                    ]
+                },
+                {
+                    "pdpType": "pdpTypeB",
+                    "desiredInstanceCount": 1,
+                    "pdpInstances": [
+                        {
+                            "instanceId": "pdpAB_1",
+                            "pdpState": "PASSIVE",
+                            "healthy": "HEALTHY"
+                        }
+                    ],
+                    "supportedPolicyTypes": [
+                        {
+                            "name": "onap.policies.monitoring.cdap.tca.hi.lo.app",
+                            "version": "1.0.0"
+                        }
+                    ],
+                    "policies": []
+                }
+            ]
+        },
+        {
+            "name": "queryGroup2",
+            "pdpGroupState": "ACTIVE",
+            "pdpSubgroups": [
+                {
+                    "pdpType": "pdpTypeA",
+                    "desiredInstanceCount": 2,
+                    "pdpInstances": [
+                        {
+                            "instanceId": "pdpBA_1",
+                            "pdpState": "PASSIVE",
+                            "healthy": "HEALTHY"
+                        },
+                        {
+                            "instanceId": "pdpBA_2",
+                            "pdpState": "PASSIVE",
+                            "healthy": "HEALTHY"
+                        }
+                    ],
+                    "supportedPolicyTypes": [
+                        {
+                            "name": "onap.policies.monitoring.cdap.tca.hi.lo.app",
+                            "version": "1.0.0"
+                        }
+                    ],
+                    "policies": [
+                        {
+                            "name": "onap.restart.tcaB",
+                            "version": "1.0.0"
+                        }
+                    ]
+                }
+            ]
+        }
+    ]
+}
diff --git a/main/src/test/resources/e2e/stateChangeGroupDeactivate.json b/main/src/test/resources/e2e/stateChangeGroupDeactivate.json
new file mode 100644 (file)
index 0000000..00ed963
--- /dev/null
@@ -0,0 +1,56 @@
+{
+    "groups": [
+        {
+            "name": "stateChangeGroupDeactivate",
+            "pdpGroupState": "ACTIVE",
+            "pdpSubgroups": [
+                {
+                    "pdpType": "pdpTypeA",
+                    "desiredInstanceCount": 2,
+                    "pdpInstances": [
+                        {
+                            "instanceId": "pdpAA_1",
+                            "pdpState": "ACTIVE",
+                            "healthy": "HEALTHY"
+                        },
+                        {
+                            "instanceId": "pdpAA_2",
+                            "pdpState": "ACTIVE",
+                            "healthy": "HEALTHY"
+                        }
+                    ],
+                    "supportedPolicyTypes": [
+                        {
+                            "name": "onap.policies.monitoring.cdap.tca.hi.lo.app",
+                            "version": "1.0.0"
+                        }
+                    ],
+                    "policies": [
+                        {
+                            "name": "onap.restart.tca",
+                            "version": "1.0.0"
+                        }
+                    ]
+                },
+                {
+                    "pdpType": "pdpTypeB",
+                    "desiredInstanceCount": 1,
+                    "pdpInstances": [
+                        {
+                            "instanceId": "pdpAB_1",
+                            "pdpState": "ACTIVE",
+                            "healthy": "HEALTHY"
+                        }
+                    ],
+                    "supportedPolicyTypes": [
+                        {
+                            "name": "onap.policies.monitoring.cdap.tca.hi.lo.app",
+                            "version": "1.0.0"
+                        }
+                    ],
+                    "policies": []
+                }
+            ]
+        }
+    ]
+}
diff --git a/main/src/test/resources/e2e/undeployPolicy.json b/main/src/test/resources/e2e/undeployPolicy.json
new file mode 100644 (file)
index 0000000..d2443d3
--- /dev/null
@@ -0,0 +1,56 @@
+{
+    "groups": [
+        {
+            "name": "undeployPolicy",
+            "pdpGroupState": "ACTIVE",
+            "pdpSubgroups": [
+                {
+                    "pdpType": "pdpTypeA",
+                    "desiredInstanceCount": 2,
+                    "pdpInstances": [
+                        {
+                            "instanceId": "pdpBA_1",
+                            "pdpState": "PASSIVE",
+                            "healthy": "HEALTHY"
+                        },
+                        {
+                            "instanceId": "pdpBA_2",
+                            "pdpState": "PASSIVE",
+                            "healthy": "HEALTHY"
+                        }
+                    ],
+                    "supportedPolicyTypes": [
+                        {
+                            "name": "onap.policies.monitoring.cdap.tca.hi.lo.app",
+                            "version": "1.0.0"
+                        }
+                    ],
+                    "policies": [
+                        {
+                            "name": "onap.restart.tcaB",
+                            "version": "1.0.0"
+                        }
+                    ]
+                },
+                {
+                    "pdpType": "pdpTypeB",
+                    "desiredInstanceCount": 1,
+                    "pdpInstances": [
+                        {
+                            "instanceId": "pdpBB_1",
+                            "pdpState": "PASSIVE",
+                            "healthy": "HEALTHY"
+                        }
+                    ],
+                    "supportedPolicyTypes": [
+                        {
+                            "name": "onap.policies.monitoring.cdap.tca.hi.lo.app",
+                            "version": "1.0.0"
+                        }
+                    ],
+                    "policies": []
+                }
+            ]
+        }
+    ]
+}
diff --git a/main/src/test/resources/e2e/undeployPolicyVersion.json b/main/src/test/resources/e2e/undeployPolicyVersion.json
new file mode 100644 (file)
index 0000000..54aa8a0
--- /dev/null
@@ -0,0 +1,56 @@
+{
+    "groups": [
+        {
+            "name": "undeployPolicyVersion",
+            "pdpGroupState": "ACTIVE",
+            "pdpSubgroups": [
+                {
+                    "pdpType": "pdpTypeA",
+                    "desiredInstanceCount": 2,
+                    "pdpInstances": [
+                        {
+                            "instanceId": "pdpCA_1",
+                            "pdpState": "PASSIVE",
+                            "healthy": "HEALTHY"
+                        },
+                        {
+                            "instanceId": "pdpCA_2",
+                            "pdpState": "PASSIVE",
+                            "healthy": "HEALTHY"
+                        }
+                    ],
+                    "supportedPolicyTypes": [
+                        {
+                            "name": "onap.policies.monitoring.cdap.tca.hi.lo.app",
+                            "version": "1.0.0"
+                        }
+                    ],
+                    "policies": [
+                        {
+                            "name": "onap.restart.tcaC",
+                            "version": "1.0.0"
+                        }
+                    ]
+                },
+                {
+                    "pdpType": "pdpTypeB",
+                    "desiredInstanceCount": 1,
+                    "pdpInstances": [
+                        {
+                            "instanceId": "pdpCB_1",
+                            "pdpState": "PASSIVE",
+                            "healthy": "HEALTHY"
+                        }
+                    ],
+                    "supportedPolicyTypes": [
+                        {
+                            "name": "onap.policies.monitoring.cdap.tca.hi.lo.app",
+                            "version": "1.0.0"
+                        }
+                    ],
+                    "policies": []
+                }
+            ]
+        }
+    ]
+}
diff --git a/main/src/test/resources/logback-test.xml b/main/src/test/resources/logback-test.xml
new file mode 100644 (file)
index 0000000..c170cc4
--- /dev/null
@@ -0,0 +1,37 @@
+<!--
+  ============LICENSE_START=======================================================
+  ONAP - Common Modules
+  ================================================================================
+  Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+  ================================================================================
+  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.
+  ============LICENSE_END=========================================================
+  -->
+
+<!-- Controls the output of logs for JUnit tests -->
+
+<configuration>
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+  <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+   <Pattern>
+    %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}.%M\(%line\) - %msg%n
+   </Pattern>
+  </encoder>
+ </appender>
+
+ <root level="info">
+  <appender-ref ref="STDOUT" />
+ </root>
+
+</configuration>
diff --git a/main/src/test/resources/parameters/PapConfigParametersStd.json b/main/src/test/resources/parameters/PapConfigParametersStd.json
new file mode 100644 (file)
index 0000000..6089c0b
--- /dev/null
@@ -0,0 +1,29 @@
+{
+    "name": "PapGroup",
+    "restServerParameters": {
+        "host": "0.0.0.0",
+        "port": ${port},
+        "userName": "healthcheck",
+        "password": "zb!XztG34",
+        "https": true
+    },
+    "pdpParameters": {
+        "updateParameters": {
+            "maxRetryCount": 1,
+            "maxWaitMs": 2
+        },
+        "stateChangeParameters": {
+            "maxRetryCount": 1,
+            "maxWaitMs": 5
+        }
+    },
+    "databaseProviderParameters": {
+        "name": "PolicyModelsProviderParameters",
+        "implementation": "org.onap.policy.models.provider.impl.DatabasePolicyModelsProviderImpl",
+        "databaseDriver": "org.h2.Driver",
+        "databaseUrl": "${dbName}",
+        "databaseUser": "policy",
+        "databasePassword": "UDAxaWNZ",
+        "persistenceUnit": "ToscaConceptTest"
+    }
+}