diff options
27 files changed, 2306 insertions, 171 deletions
diff --git a/main/src/main/java/org/onap/policy/pap/main/comm/PdpModifyRequestMap.java b/main/src/main/java/org/onap/policy/pap/main/comm/PdpModifyRequestMap.java index 0d012c0a..04bab743 100644 --- a/main/src/main/java/org/onap/policy/pap/main/comm/PdpModifyRequestMap.java +++ b/main/src/main/java/org/onap/policy/pap/main/comm/PdpModifyRequestMap.java @@ -91,6 +91,15 @@ public class PdpModifyRequestMap { } /** + * 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. * * @param pdpName PDP name diff --git a/main/src/main/java/org/onap/policy/pap/main/startstop/Main.java b/main/src/main/java/org/onap/policy/pap/main/startstop/Main.java index e8b48e60..6351fa80 100644 --- a/main/src/main/java/org/onap/policy/pap/main/startstop/Main.java +++ b/main/src/main/java/org/onap/policy/pap/main/startstop/Main.java @@ -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(); diff --git a/main/src/test/java/org/onap/policy/pap/main/parameters/CommonTestData.java b/main/src/test/java/org/onap/policy/pap/main/parameters/CommonTestData.java index 10e500fb..14000e60 100644 --- a/main/src/test/java/org/onap/policy/pap/main/parameters/CommonTestData.java +++ b/main/src/test/java/org/onap/policy/pap/main/parameters/CommonTestData.java @@ -21,17 +21,15 @@ 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\""); } } diff --git a/main/src/test/java/org/onap/policy/pap/main/parameters/TestPapParameterGroup.java b/main/src/test/java/org/onap/policy/pap/main/parameters/TestPapParameterGroup.java index 2450a750..6a1fbba2 100644 --- a/main/src/test/java/org/onap/policy/pap/main/parameters/TestPapParameterGroup.java +++ b/main/src/test/java/org/onap/policy/pap/main/parameters/TestPapParameterGroup.java @@ -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() diff --git a/main/src/test/java/org/onap/policy/pap/main/parameters/TestPdpParameters.java b/main/src/test/java/org/onap/policy/pap/main/parameters/TestPdpParameters.java index 05bcc103..eb9a6e8b 100644 --- a/main/src/test/java/org/onap/policy/pap/main/parameters/TestPdpParameters.java +++ b/main/src/test/java/org/onap/policy/pap/main/parameters/TestPdpParameters.java @@ -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('\'', '"'))); } } diff --git a/main/src/test/java/org/onap/policy/pap/main/rest/CommonPapRestServer.java b/main/src/test/java/org/onap/policy/pap/main/rest/CommonPapRestServer.java index e7b412dc..d4b69f2e 100644 --- a/main/src/test/java/org/onap/policy/pap/main/rest/CommonPapRestServer.java +++ b/main/src/test/java/org/onap/policy/pap/main/rest/CommonPapRestServer.java @@ -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 index 00000000..7e217423 --- /dev/null +++ b/main/src/test/java/org/onap/policy/pap/main/rest/e2e/End2EndBase.java @@ -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 index 00000000..fe0f682a --- /dev/null +++ b/main/src/test/java/org/onap/policy/pap/main/rest/e2e/End2EndContext.java @@ -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 index 00000000..f429afbd --- /dev/null +++ b/main/src/test/java/org/onap/policy/pap/main/rest/e2e/HealthCheckTest.java @@ -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 index 00000000..9ffe1035 --- /dev/null +++ b/main/src/test/java/org/onap/policy/pap/main/rest/e2e/PdpGroupDeleteTest.java @@ -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 index 00000000..5279236a --- /dev/null +++ b/main/src/test/java/org/onap/policy/pap/main/rest/e2e/PdpGroupDeployTest.java @@ -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 index 00000000..5f16751c --- /dev/null +++ b/main/src/test/java/org/onap/policy/pap/main/rest/e2e/PdpGroupQueryTest.java @@ -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 index 00000000..6fdd516b --- /dev/null +++ b/main/src/test/java/org/onap/policy/pap/main/rest/e2e/PdpGroupStateChangeTest.java @@ -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 index 00000000..13492cf9 --- /dev/null +++ b/main/src/test/java/org/onap/policy/pap/main/rest/e2e/StatisticsTest.java @@ -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 index 00000000..4e085f76 --- /dev/null +++ b/main/src/test/resources/e2e/PapConfigParameters.json @@ -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 index 00000000..1c8774be --- /dev/null +++ b/main/src/test/resources/e2e/createGroups.json @@ -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 index 00000000..4351d5c1 --- /dev/null +++ b/main/src/test/resources/e2e/deleteGroup.json @@ -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 index 00000000..4cafe77b --- /dev/null +++ b/main/src/test/resources/e2e/deployPolicies.json @@ -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 index 00000000..c6139516 --- /dev/null +++ b/main/src/test/resources/e2e/deployPoliciesReq.json @@ -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 index 00000000..98b64522 --- /dev/null +++ b/main/src/test/resources/e2e/monitoring.policy-type.yaml @@ -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 index 00000000..fe15b479 --- /dev/null +++ b/main/src/test/resources/e2e/monitoring.policy.yaml @@ -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 index 00000000..2a7b4edc --- /dev/null +++ b/main/src/test/resources/e2e/queryGroup.json @@ -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 index 00000000..00ed9639 --- /dev/null +++ b/main/src/test/resources/e2e/stateChangeGroupDeactivate.json @@ -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 index 00000000..d2443d38 --- /dev/null +++ b/main/src/test/resources/e2e/undeployPolicy.json @@ -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 index 00000000..54aa8a00 --- /dev/null +++ b/main/src/test/resources/e2e/undeployPolicyVersion.json @@ -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 index 00000000..c170cc41 --- /dev/null +++ b/main/src/test/resources/logback-test.xml @@ -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 index 00000000..6089c0b7 --- /dev/null +++ b/main/src/test/resources/parameters/PapConfigParametersStd.json @@ -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" + } +} |