diff options
29 files changed, 1665 insertions, 510 deletions
diff --git a/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/impl/ModelHandlerFacade.java b/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/impl/ModelHandlerFacade.java index db4a9ab08..da14e810a 100644 --- a/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/impl/ModelHandlerFacade.java +++ b/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/impl/ModelHandlerFacade.java @@ -33,7 +33,6 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Properties; import java.util.Set; - import org.onap.policy.apex.model.basicmodel.concepts.ApexException; import org.onap.policy.apex.model.basicmodel.concepts.ApexRuntimeException; import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey; @@ -528,7 +527,7 @@ public class ModelHandlerFacade { try { AxPolicyModel mergedPolicyModel = PolicyModelMerger.getMergedPolicyModel(apexModel.getPolicyModel(), - mergeInPolicyModel, keepOriginal, false); + mergeInPolicyModel, keepOriginal, false, false); apexModel.setPolicyModel(mergedPolicyModel != null ? mergedPolicyModel : new AxPolicyModel()); return new ApexApiResult(); } catch (ApexModelException e) { @@ -555,7 +554,7 @@ public class ModelHandlerFacade { try { AxPolicyModel mergedPolicyModel = PolicyModelMerger.getMergedPolicyModel(apexModel.getPolicyModel(), - mergeInPolicyModel, keepOriginal, false); + mergeInPolicyModel, keepOriginal, false, false); apexModel.setPolicyModel(mergedPolicyModel != null ? mergedPolicyModel : new AxPolicyModel()); return new ApexApiResult(); } catch (ApexModelException e) { diff --git a/model/policy-model/pom.xml b/model/policy-model/pom.xml index b0708ae1e..a2d3b4c8c 100644 --- a/model/policy-model/pom.xml +++ b/model/policy-model/pom.xml @@ -44,6 +44,11 @@ <artifactId>event-model</artifactId> <version>${project.version}</version> </dependency> + <dependency> + <groupId>org.assertj</groupId> + <artifactId>assertj-core</artifactId> + <scope>test</scope> + </dependency> </dependencies> <build> diff --git a/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelMerger.java b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelMerger.java index 28133cefa..37c3b2368 100644 --- a/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelMerger.java +++ b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelMerger.java @@ -1,32 +1,38 @@ /*- * ============LICENSE_START======================================================= * Copyright (C) 2016-2018 Ericsson. All rights reserved. + * Modifications Copyright (C) 2019 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * * SPDX-License-Identifier: Apache-2.0 * ============LICENSE_END========================================================= */ package org.onap.policy.apex.model.policymodel.handling; -import java.util.Set; -import java.util.TreeSet; - +import java.util.Map; +import java.util.Map.Entry; import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey; +import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInfo; import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult; import org.onap.policy.apex.model.basicmodel.handling.ApexModelException; +import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum; +import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema; +import org.onap.policy.apex.model.eventmodel.concepts.AxEvent; +import org.onap.policy.apex.model.policymodel.concepts.AxPolicy; import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel; +import org.onap.policy.apex.model.policymodel.concepts.AxTask; import org.slf4j.ext.XLogger; import org.slf4j.ext.XLoggerFactory; @@ -42,7 +48,8 @@ public final class PolicyModelMerger { /** * Private constructor used to prevent sub class instantiation. */ - private PolicyModelMerger() {} + private PolicyModelMerger() { + } /** * Get a merged policy model with information from two policy models merged into a larger policy @@ -52,12 +59,14 @@ public final class PolicyModelMerger { * @param rightPolicyModel the policies to include in sub policy model * @param useLeftOnMatches if true, uses concepts from the left model if concepts with common * keys are found, if false it uses the concepts from the right model + * @param failOnDuplicateKeys whether to fail or not on the occurence of duplicate concept keys * @return the new Destination Model * @throws ApexModelException on model transfer errors */ public static AxPolicyModel getMergedPolicyModel(final AxPolicyModel leftPolicyModel, - final AxPolicyModel rightPolicyModel, final boolean useLeftOnMatches) throws ApexModelException { - return getMergedPolicyModel(leftPolicyModel, rightPolicyModel, useLeftOnMatches, false); + final AxPolicyModel rightPolicyModel, final boolean useLeftOnMatches, final boolean failOnDuplicateKeys) + throws ApexModelException { + return getMergedPolicyModel(leftPolicyModel, rightPolicyModel, useLeftOnMatches, false, failOnDuplicateKeys); } /** @@ -69,89 +78,105 @@ public final class PolicyModelMerger { * @param useLeftOnMatches if true, uses concepts from the left model if concepts with common * keys are found, if false it uses the concepts from the right model * @param ignoreInvalidSource Ignore errors on the source model, do the best you can + * @param failOnDuplicateKeys whether to fail or not on the occurence of duplicate concept keys * @return the new Destination Model * @throws ApexModelException on model transfer errors */ public static AxPolicyModel getMergedPolicyModel(final AxPolicyModel leftPolicyModel, - final AxPolicyModel rightPolicyModel, final boolean useLeftOnMatches, final boolean ignoreInvalidSource) - throws ApexModelException { - // Validate the left model - if (!ignoreInvalidSource) { - final AxValidationResult leftValidationResult = new AxValidationResult(); - leftPolicyModel.validate(leftValidationResult); - if (!leftValidationResult.isValid()) { - String message = "left model is invalid: " + leftValidationResult.toString(); - LOGGER.warn(message); - throw new ApexModelException(message); - } - } + final AxPolicyModel rightPolicyModel, final boolean useLeftOnMatches, final boolean ignoreInvalidSource, + final boolean failOnDuplicateKeys) throws ApexModelException { - // Validate the right model if (!ignoreInvalidSource) { - final AxValidationResult rightValidationResult = new AxValidationResult(); - rightPolicyModel.validate(rightValidationResult); - if (!rightValidationResult.isValid()) { - String message = "right model is invalid: " + rightValidationResult.toString(); - LOGGER.warn(message); - throw new ApexModelException(message); - } + validateModels(leftPolicyModel, "left"); + validateModels(rightPolicyModel, "right"); } // The new policy model uses the favoured copy side as its base - final AxPolicyModel mergedPolicyModel = (useLeftOnMatches ? new AxPolicyModel(leftPolicyModel) - : new AxPolicyModel(rightPolicyModel)); + final AxPolicyModel mergedPolicyModel = + (useLeftOnMatches ? new AxPolicyModel(leftPolicyModel) : new AxPolicyModel(rightPolicyModel)); // The Compared to policy model is the unfavoured side - final AxPolicyModel copyFromPolicyModel = (useLeftOnMatches ? rightPolicyModel : leftPolicyModel); - - // Get the keys to copy over - final Set<AxArtifactKey> copyOverKeyInfoKeys = - new TreeSet<>(copyFromPolicyModel.getKeyInformation().getKeyInfoMap().keySet()); - final Set<AxArtifactKey> copyOverContextSchemaKeys = - new TreeSet<>(copyFromPolicyModel.getSchemas().getSchemasMap().keySet()); - final Set<AxArtifactKey> copyOverEventKeys = - new TreeSet<>(copyFromPolicyModel.getEvents().getEventMap().keySet()); - final Set<AxArtifactKey> copyOverContextAlbumKeys = - new TreeSet<>(copyFromPolicyModel.getAlbums().getAlbumsMap().keySet()); - final Set<AxArtifactKey> copyOverTaskKeys = new TreeSet<>(copyFromPolicyModel.getTasks().getTaskMap().keySet()); - final Set<AxArtifactKey> copyOverPolicyKeys = - new TreeSet<>(copyFromPolicyModel.getPolicies().getPolicyMap().keySet()); - - // Remove keys that already exist - copyOverKeyInfoKeys.removeAll(mergedPolicyModel.getKeyInformation().getKeyInfoMap().keySet()); - copyOverContextSchemaKeys.removeAll(mergedPolicyModel.getSchemas().getSchemasMap().keySet()); - copyOverEventKeys.removeAll(mergedPolicyModel.getEvents().getEventMap().keySet()); - copyOverContextAlbumKeys.removeAll(mergedPolicyModel.getAlbums().getAlbumsMap().keySet()); - copyOverTaskKeys.removeAll(mergedPolicyModel.getTasks().getTaskMap().keySet()); - copyOverPolicyKeys.removeAll(mergedPolicyModel.getPolicies().getPolicyMap().keySet()); + final AxPolicyModel copyFromPolicyModel = + (useLeftOnMatches ? new AxPolicyModel(rightPolicyModel) : new AxPolicyModel(leftPolicyModel)); - // Now add all the concepts that must be copied over - for (final AxArtifactKey keyInfoKey : copyOverKeyInfoKeys) { - mergedPolicyModel.getKeyInformation().getKeyInfoMap().put(keyInfoKey, - copyFromPolicyModel.getKeyInformation().getKeyInfoMap().get(keyInfoKey)); - } - for (final AxArtifactKey contextSchemaKey : copyOverContextSchemaKeys) { - mergedPolicyModel.getSchemas().getSchemasMap().put(contextSchemaKey, - copyFromPolicyModel.getSchemas().getSchemasMap().get(contextSchemaKey)); - } - for (final AxArtifactKey eventKey : copyOverEventKeys) { - mergedPolicyModel.getEvents().getEventMap().put(eventKey, - copyFromPolicyModel.getEvents().getEventMap().get(eventKey)); - } - for (final AxArtifactKey contextAlbumKey : copyOverContextAlbumKeys) { - mergedPolicyModel.getAlbums().getAlbumsMap().put(contextAlbumKey, - copyFromPolicyModel.getAlbums().getAlbumsMap().get(contextAlbumKey)); - } - for (final AxArtifactKey taskKey : copyOverTaskKeys) { - mergedPolicyModel.getTasks().getTaskMap().put(taskKey, - copyFromPolicyModel.getTasks().getTaskMap().get(taskKey)); - } - for (final AxArtifactKey policyKey : copyOverPolicyKeys) { - mergedPolicyModel.getPolicies().getPolicyMap().put(policyKey, - copyFromPolicyModel.getPolicies().getPolicyMap().get(policyKey)); + Map<AxArtifactKey, AxKeyInfo> mergedKeyInfoMap = mergedPolicyModel.getKeyInformation().getKeyInfoMap(); + Map<AxArtifactKey, AxContextSchema> mergedSchemasMap = mergedPolicyModel.getSchemas().getSchemasMap(); + Map<AxArtifactKey, AxEvent> mergedEventMap = mergedPolicyModel.getEvents().getEventMap(); + Map<AxArtifactKey, AxContextAlbum> mergedAlbumsMap = mergedPolicyModel.getAlbums().getAlbumsMap(); + Map<AxArtifactKey, AxTask> mergedTaskMap = mergedPolicyModel.getTasks().getTaskMap(); + Map<AxArtifactKey, AxPolicy> mergedPolicyMap = mergedPolicyModel.getPolicies().getPolicyMap(); + + Map<AxArtifactKey, AxKeyInfo> copyOverKeyInfoMap = copyFromPolicyModel.getKeyInformation().getKeyInfoMap(); + Map<AxArtifactKey, AxContextSchema> copyOverSchemasMap = copyFromPolicyModel.getSchemas().getSchemasMap(); + Map<AxArtifactKey, AxEvent> copyOverEventMap = copyFromPolicyModel.getEvents().getEventMap(); + Map<AxArtifactKey, AxContextAlbum> copyOverAlbumsMap = copyFromPolicyModel.getAlbums().getAlbumsMap(); + Map<AxArtifactKey, AxTask> copyOverTaskMap = copyFromPolicyModel.getTasks().getTaskMap(); + Map<AxArtifactKey, AxPolicy> copyOverPolicyMap = copyFromPolicyModel.getPolicies().getPolicyMap(); + + if (failOnDuplicateKeys) { + StringBuilder errorMessage = new StringBuilder(); + checkForDuplicateContextItem(mergedSchemasMap, copyOverSchemasMap, errorMessage, "schema"); + checkForDuplicateItem(mergedEventMap, copyOverEventMap, errorMessage, "event"); + checkForDuplicateContextItem(mergedAlbumsMap, copyOverAlbumsMap, errorMessage, "album"); + checkForDuplicateItem(mergedTaskMap, copyOverTaskMap, errorMessage, "task"); + checkForDuplicateItem(mergedPolicyMap, copyOverPolicyMap, errorMessage, "policy"); + if (errorMessage.length() > 0) { + throw new ApexModelException(errorMessage.toString()); + } + } else { + // Remove entries that already exist + copyOverKeyInfoMap.keySet().removeIf(mergedKeyInfoMap::containsKey); + copyOverSchemasMap.keySet().removeIf(mergedSchemasMap::containsKey); + copyOverEventMap.keySet().removeIf(mergedEventMap::containsKey); + copyOverAlbumsMap.keySet().removeIf(mergedAlbumsMap::containsKey); + copyOverTaskMap.keySet().removeIf(mergedTaskMap::containsKey); + copyOverPolicyMap.keySet().removeIf(mergedPolicyMap::containsKey); } + // Now add all the concepts that must be copied over + mergedKeyInfoMap.putAll(copyOverKeyInfoMap); + mergedSchemasMap.putAll(copyOverSchemasMap); + mergedEventMap.putAll(copyOverEventMap); + mergedAlbumsMap.putAll(copyOverAlbumsMap); + mergedTaskMap.putAll(copyOverTaskMap); + mergedPolicyMap.putAll(copyOverPolicyMap); // That's it, return the model return mergedPolicyModel; } + + private static <V> void checkForDuplicateItem(Map<AxArtifactKey, V> mergedItemsMap, + Map<AxArtifactKey, V> copyOverItemsMap, StringBuilder errorMessage, String itemType) { + for (AxArtifactKey key : copyOverItemsMap.keySet()) { + if (mergedItemsMap.containsKey(key)) { + errorMessage.append("\n Duplicate " + itemType + " found - ").append(key.getId()); + } + } + } + + private static <V> void checkForDuplicateContextItem(Map<AxArtifactKey, V> mergedItemsMap, + Map<AxArtifactKey, V> copyOverItemsMap, StringBuilder errorMessage, String itemType) { + for (Entry<AxArtifactKey, V> entry : copyOverItemsMap.entrySet()) { + V item = mergedItemsMap.get(entry.getKey()); + // same context schema name with different definitions cannot occur in multiple policies + if (null != item) { + if (item.equals(entry.getValue())) { + LOGGER.info("Same {} - {} is used by multiple policies.", itemType, entry.getKey().getId()); + } else { + errorMessage.append("\n Same " + itemType + " - ").append(entry.getKey().getId()) + .append(" with different definitions used in different policies"); + } + } + } + } + + private static void validateModels(AxPolicyModel policyModel, String position) throws ApexModelException { + // Validate the model + final AxValidationResult validationResult = new AxValidationResult(); + policyModel.validate(validationResult); + if (!validationResult.isValid()) { + String message = position + " model is invalid: " + validationResult.toString(); + LOGGER.warn(message); + throw new ApexModelException(message); + } + } } diff --git a/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelMergerTest.java b/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelMergerTest.java index b477c47cd..560ddc6a9 100644 --- a/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelMergerTest.java +++ b/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelMergerTest.java @@ -1,111 +1,86 @@ /*- * ============LICENSE_START======================================================= * Copyright (C) 2016-2018 Ericsson. All rights reserved. + * Modifications Copyright (C) 2019 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * * SPDX-License-Identifier: Apache-2.0 * ============LICENSE_END========================================================= */ package org.onap.policy.apex.model.policymodel.handling; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; import org.junit.Test; import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey; import org.onap.policy.apex.model.basicmodel.handling.ApexModelException; import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel; -import org.onap.policy.apex.model.policymodel.handling.PolicyModelMerger; /** * Test model merging. - * + * * @author Liam Fallon (liam.fallon@ericsson.com) */ public class PolicyModelMergerTest { @Test - public void testPolicyModelMerger() { + public void testPolicyModelMerger() throws ApexModelException { final AxPolicyModel leftPolicyModel = new SupportApexPolicyModelCreator().getModel(); - AxPolicyModel rightPolicyModel = new SupportApexPolicyModelCreator().getModel(); + final AxPolicyModel rightPolicyModel = new SupportApexPolicyModelCreator().getModel(); - try { - final AxPolicyModel mergedPolicyModel = PolicyModelMerger.getMergedPolicyModel(leftPolicyModel, - rightPolicyModel, false); - assertEquals(leftPolicyModel, mergedPolicyModel); - assertEquals(rightPolicyModel, mergedPolicyModel); - } catch (final ApexModelException e) { - fail("test should not throw an exception"); - } + AxPolicyModel mergedPolicyModel = + PolicyModelMerger.getMergedPolicyModel(leftPolicyModel, rightPolicyModel, false, false); + assertEquals(leftPolicyModel, mergedPolicyModel); + assertEquals(rightPolicyModel, mergedPolicyModel); leftPolicyModel.setKey(new AxArtifactKey("LeftPolicyModel", "0.0.1")); - try { - PolicyModelMerger.getMergedPolicyModel(leftPolicyModel, rightPolicyModel, false); - fail("test should throw an exception here"); - } catch (final ApexModelException e) { - assertEquals("left model is invalid: \n***validation of model fai", e.getMessage().substring(0, 50)); - } + assertThatThrownBy( + () -> PolicyModelMerger.getMergedPolicyModel(leftPolicyModel, rightPolicyModel, false, false)) + .hasMessageContaining("left model is invalid: \n***validation of model failed"); leftPolicyModel.setKey(new AxArtifactKey("LeftPolicyModel", "0.0.1")); - try { - assertNotNull(PolicyModelMerger.getMergedPolicyModel(leftPolicyModel, rightPolicyModel, false, true)); - } catch (final ApexModelException e) { - fail("test should not throw an exception"); - } + assertNotNull(PolicyModelMerger.getMergedPolicyModel(leftPolicyModel, rightPolicyModel, false, true, false)); leftPolicyModel.getKeyInformation().generateKeyInfo(leftPolicyModel); - try { - final AxPolicyModel mergedPolicyModel = PolicyModelMerger.getMergedPolicyModel(leftPolicyModel, - rightPolicyModel, true); - assertNotNull(mergedPolicyModel); - } catch (final ApexModelException e) { - fail("test should not throw an exception"); - } + mergedPolicyModel = PolicyModelMerger.getMergedPolicyModel(leftPolicyModel, rightPolicyModel, true, false); + assertNotNull(mergedPolicyModel); rightPolicyModel.setKey(new AxArtifactKey("RightPolicyModel", "0.0.1")); - try { - PolicyModelMerger.getMergedPolicyModel(leftPolicyModel, rightPolicyModel, false); - fail("test should throw an exception here"); - } catch (final ApexModelException e) { - assertEquals("right model is invalid: \n***validation of model fa", e.getMessage().substring(0, 50)); - } + assertThatThrownBy( + () -> PolicyModelMerger.getMergedPolicyModel(leftPolicyModel, rightPolicyModel, false, false)) + .hasMessageContaining("right model is invalid: \n***validation of model failed"); rightPolicyModel.setKey(new AxArtifactKey("RightPolicyModel", "0.0.1")); - try { - assertNotNull(PolicyModelMerger.getMergedPolicyModel(leftPolicyModel, rightPolicyModel, false, true)); - } catch (final ApexModelException e) { - fail("test should not throw an exception"); - } + assertNotNull(PolicyModelMerger.getMergedPolicyModel(leftPolicyModel, rightPolicyModel, false, true, false)); rightPolicyModel.getKeyInformation().generateKeyInfo(rightPolicyModel); - try { - final AxPolicyModel mergedPolicyModel = PolicyModelMerger.getMergedPolicyModel(leftPolicyModel, - rightPolicyModel, false); - assertNotNull(mergedPolicyModel); - } catch (final ApexModelException e) { - fail("test should not throw an exception"); - } + mergedPolicyModel = PolicyModelMerger.getMergedPolicyModel(leftPolicyModel, rightPolicyModel, false, false); + assertNotNull(mergedPolicyModel); - rightPolicyModel = new SupportApexPolicyModelCreator().getAnotherModel(); - try { - final AxPolicyModel mergedPolicyModel = PolicyModelMerger.getMergedPolicyModel(leftPolicyModel, - rightPolicyModel, true); - assertNotNull(mergedPolicyModel); - } catch (final ApexModelException e) { - fail("test should not throw an exception"); - } + final AxPolicyModel rightPolicyModel2 = new SupportApexPolicyModelCreator().getAnotherModel(); + mergedPolicyModel = PolicyModelMerger.getMergedPolicyModel(leftPolicyModel, rightPolicyModel2, true, false); + assertNotNull(mergedPolicyModel); + + mergedPolicyModel = PolicyModelMerger.getMergedPolicyModel(leftPolicyModel, rightPolicyModel2, true, true); + assertNotNull(mergedPolicyModel); + + final AxPolicyModel rightPolicyModel3 = new SupportApexPolicyModelCreator().getModel(); + assertThatThrownBy( + () -> PolicyModelMerger.getMergedPolicyModel(leftPolicyModel, rightPolicyModel3, true, true)) + .hasMessageContaining("Duplicate policy found"); } } diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/RestRequestorTest.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/RestRequestorTest.java index 85027cc5b..424689cf4 100644 --- a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/RestRequestorTest.java +++ b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/RestRequestorTest.java @@ -21,7 +21,18 @@ package org.onap.policy.apex.plugins.event.carrier.restrequestor; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + import com.google.gson.Gson; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.PrintStream; +import java.util.Map; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.core.Response; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; @@ -35,18 +46,6 @@ import org.onap.policy.common.endpoints.http.server.HttpServletServerFactoryInst import org.onap.policy.common.gson.GsonMessageBodyHandler; import org.onap.policy.common.utils.network.NetworkUtil; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.core.Response; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.PrintStream; -import java.util.Map; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - /** * The Class TestRestRequestor. */ @@ -76,7 +75,7 @@ public class RestRequestorTest { server.start(); - if (!NetworkUtil.isTcpPortOpen("localHost", PORT, 2000, 1L)) { + if (!NetworkUtil.isTcpPortOpen("localHost", PORT, 60, 500L)) { throw new IllegalStateException("port " + PORT + " is still not in use"); } } diff --git a/services/services-engine/pom.xml b/services/services-engine/pom.xml index 0fafa09e6..a4a877657 100644 --- a/services/services-engine/pom.xml +++ b/services/services-engine/pom.xml @@ -63,6 +63,17 @@ <artifactId>mockito-all</artifactId> <scope>test</scope> </dependency> + <dependency> + <groupId>org.onap.policy.models</groupId> + <artifactId>policy-models-pdp</artifactId> + <exclusions> + <exclusion> + <groupId>javax.ws.rs</groupId> + <artifactId>javax.ws.rs-api</artifactId> + </exclusion> + </exclusions> + <version>${version.policy.models}</version> + </dependency> </dependencies> <build> diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/main/ApexActivator.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/main/ApexActivator.java index 3aa1f17ff..2c3fac151 100644 --- a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/main/ApexActivator.java +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/main/ApexActivator.java @@ -24,17 +24,24 @@ package org.onap.policy.apex.service.engine.main; import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; - +import java.util.stream.Stream; +import lombok.Getter; import org.onap.policy.apex.model.basicmodel.concepts.ApexException; +import org.onap.policy.apex.model.basicmodel.handling.ApexModelException; import org.onap.policy.apex.model.basicmodel.service.ModelService; +import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel; +import org.onap.policy.apex.model.policymodel.handling.PolicyModelMerger; import org.onap.policy.apex.model.utilities.TextFileUtils; import org.onap.policy.apex.service.engine.engdep.EngDepMessagingService; +import org.onap.policy.apex.service.engine.event.ApexEventException; import org.onap.policy.apex.service.engine.runtime.EngineService; import org.onap.policy.apex.service.engine.runtime.impl.EngineServiceImpl; import org.onap.policy.apex.service.parameters.ApexParameters; +import org.onap.policy.apex.service.parameters.engineservice.EngineServiceParameters; import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters; import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerPeeredMode; import org.onap.policy.common.parameters.ParameterService; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifier; import org.slf4j.ext.XLogger; import org.slf4j.ext.XLoggerFactory; @@ -45,11 +52,14 @@ import org.slf4j.ext.XLoggerFactory; * @author Liam Fallon (liam.fallon@ericsson.com) */ public class ApexActivator { + private static final String APEX_ENGINE_FAILED_MSG = "Apex engine failed to start as a service"; + // The logger for this class private static final XLogger LOGGER = XLoggerFactory.getXLogger(ApexActivator.class); - // The parameters of this Apex activator - private final ApexParameters apexParameters; + // The parameters of the Apex activator when running with multiple policies + @Getter + private Map<ToscaPolicyIdentifier, ApexParameters> apexParametersMap; // Event unmarshalers are used to receive events asynchronously into Apex private final Map<String, ApexEventUnmarshaller> unmarshallerMap = new LinkedHashMap<>(); @@ -62,13 +72,16 @@ public class ApexActivator { // and synchronous events from the engine. private ApexEngineServiceHandler engineServiceHandler = null; + // The engine service + private EngineService apexEngineService; + /** * Instantiate the activator for the Apex engine as a complete service. * - * @param parameters the apex parameters for the Apex service + * @param parametersMap the apex parameters map for the Apex service */ - public ApexActivator(final ApexParameters parameters) { - apexParameters = parameters; + public ApexActivator(Map<ToscaPolicyIdentifier, ApexParameters> parametersMap) { + apexParametersMap = parametersMap; } /** @@ -80,61 +93,118 @@ public class ApexActivator { LOGGER.debug("Apex engine starting as a service . . ."); try { - // Create engine with specified thread count - LOGGER.debug("starting apex engine service . . ."); - final EngineService apexEngineService = - EngineServiceImpl.create(apexParameters.getEngineServiceParameters()); - - // Instantiate and start the messaging service for Deployment - LOGGER.debug("starting apex deployment service . . ."); - final EngDepMessagingService engDepService = new EngDepMessagingService(apexEngineService, - apexParameters.getEngineServiceParameters().getDeploymentPort()); - engDepService.start(); - - // Create the engine holder to hold the engine's references and act as an event receiver - engineServiceHandler = new ApexEngineServiceHandler(apexEngineService, engDepService); - - // Check if a policy model file has been specified - if (apexParameters.getEngineServiceParameters().getPolicyModelFileName() != null) { - LOGGER.debug("deploying policy model in \"" - + apexParameters.getEngineServiceParameters().getPolicyModelFileName() + ApexParameters apexParameters = apexParametersMap.values().iterator().next(); + // totalInstanceCount is the sum of instance counts required as per each policy + int totalInstanceCount = apexParametersMap.values().stream() + .mapToInt(p -> p.getEngineServiceParameters().getInstanceCount()).sum(); + apexParameters.getEngineServiceParameters().setInstanceCount(totalInstanceCount); + instantiateEngine(apexParameters); + Map<ToscaPolicyIdentifier, AxPolicyModel> policyModelsMap = new LinkedHashMap<>(); + Map<String, EventHandlerParameters> inputParametersMap = new LinkedHashMap<>(); + Map<String, EventHandlerParameters> outputParametersMap = new LinkedHashMap<>(); + + for (Entry<ToscaPolicyIdentifier, ApexParameters> apexParamsEntry : apexParametersMap.entrySet()) { + ApexParameters apexParams = apexParamsEntry.getValue(); + boolean duplicateInputParameterExist = + apexParams.getEventInputParameters().keySet().stream().anyMatch(inputParametersMap::containsKey); + boolean duplicateOutputParameterExist = + apexParams.getEventOutputParameters().keySet().stream().anyMatch(outputParametersMap::containsKey); + if (duplicateInputParameterExist || duplicateOutputParameterExist) { + LOGGER.error("I/O Parameters for " + apexParamsEntry.getKey().getName() + ":" + + apexParamsEntry.getKey().getVersion() + + " has duplicates. So this policy is not executed"); + apexParametersMap.remove(apexParamsEntry.getKey()); + continue; + } else { + inputParametersMap.putAll(apexParams.getEventInputParameters()); + outputParametersMap.putAll(apexParams.getEventOutputParameters()); + } + // Check if a policy model file has been specified + if (apexParams.getEngineServiceParameters().getPolicyModelFileName() != null) { + LOGGER.debug("deploying policy model in \"" + + apexParams.getEngineServiceParameters().getPolicyModelFileName() + "\" to the apex engines . . ."); - // Set the policy model in the engine - final String policyModelString = TextFileUtils - .getTextFileAsString(apexParameters.getEngineServiceParameters().getPolicyModelFileName()); - apexEngineService.updateModel(apexParameters.getEngineServiceParameters().getEngineKey(), - policyModelString, true); + final String policyModelString = TextFileUtils + .getTextFileAsString(apexParams.getEngineServiceParameters().getPolicyModelFileName()); + AxPolicyModel policyModel = EngineServiceImpl + .createModel(apexParams.getEngineServiceParameters().getEngineKey(), policyModelString); + policyModelsMap.put(apexParamsEntry.getKey(), policyModel); + } } + AxPolicyModel finalPolicyModel = aggregatePolicyModels(policyModelsMap); + // Set the policy model in the engine + apexEngineService.updateModel(apexParameters.getEngineServiceParameters().getEngineKey(), + finalPolicyModel, true); + setUpMarshallerAndUnmarshaller(apexParameters.getEngineServiceParameters(), inputParametersMap, + outputParametersMap); + setUpmarshalerPairings(inputParametersMap); + } catch (final Exception e) { + LOGGER.debug(APEX_ENGINE_FAILED_MSG, e); + throw new ApexActivatorException(APEX_ENGINE_FAILED_MSG, e); + } - // Producer parameters specify what event marshalers to handle events leaving Apex are - // set up and how they are set up - for (final Entry<String, EventHandlerParameters> outputParameters : apexParameters - .getEventOutputParameters().entrySet()) { - final ApexEventMarshaller marshaller = new ApexEventMarshaller(outputParameters.getKey(), - apexParameters.getEngineServiceParameters(), outputParameters.getValue()); - marshaller.init(); - apexEngineService.registerActionListener(outputParameters.getKey(), marshaller); - marshallerMap.put(outputParameters.getKey(), marshaller); - } + LOGGER.debug("Apex engine started as a service"); + } - // Consumer parameters specify what event unmarshalers to handle events coming into Apex - // are set up and how they are set up - for (final Entry<String, EventHandlerParameters> inputParameters : apexParameters.getEventInputParameters() - .entrySet()) { - final ApexEventUnmarshaller unmarshaller = new ApexEventUnmarshaller(inputParameters.getKey(), - apexParameters.getEngineServiceParameters(), inputParameters.getValue()); - unmarshallerMap.put(inputParameters.getKey(), unmarshaller); - unmarshaller.init(engineServiceHandler); - } + private AxPolicyModel aggregatePolicyModels(Map<ToscaPolicyIdentifier, AxPolicyModel> policyModelsMap) { + Map.Entry<ToscaPolicyIdentifier, AxPolicyModel> firstEntry = policyModelsMap.entrySet().iterator().next(); + Stream<Entry<ToscaPolicyIdentifier, AxPolicyModel>> policyModelStream = + policyModelsMap.entrySet().stream().skip(1); + Entry<ToscaPolicyIdentifier, AxPolicyModel> finalPolicyModelEntry = + policyModelStream.reduce(firstEntry, ((entry1, entry2) -> { + try { + entry1.setValue( + PolicyModelMerger.getMergedPolicyModel(entry1.getValue(), entry2.getValue(), true, true)); + } catch (ApexModelException exc) { + LOGGER.error("Policy model for " + entry2.getKey().getName() + ":" + entry2.getKey().getVersion() + + " is having duplicates. So this policy is not executed", exc.getMessage()); + apexParametersMap.remove(entry2.getKey()); + } + return entry1; + })); + return finalPolicyModelEntry.getValue(); + } - setUpmarshalerPairings(); - } catch (final Exception e) { - LOGGER.debug("Apex engine failed to start as a service", e); - throw new ApexActivatorException("Apex engine failed to start as a service", e); + private void setUpMarshallerAndUnmarshaller(EngineServiceParameters engineServiceParameters, + Map<String, EventHandlerParameters> inputParametersMap, Map<String, EventHandlerParameters> outputParametersMap) + throws ApexEventException { + // Producer parameters specify what event marshalers to handle events leaving Apex are + // set up and how they are set up + for (Entry<String, EventHandlerParameters> outputParameters : outputParametersMap.entrySet()) { + final ApexEventMarshaller marshaller = new ApexEventMarshaller(outputParameters.getKey(), + engineServiceParameters, outputParameters.getValue()); + marshaller.init(); + apexEngineService.registerActionListener(outputParameters.getKey(), marshaller); + marshallerMap.put(outputParameters.getKey(), marshaller); } + // Consumer parameters specify what event unmarshalers to handle events coming into Apex + // are set up and how they are set up + for (final Entry<String, EventHandlerParameters> inputParameters : inputParametersMap.entrySet()) { + final ApexEventUnmarshaller unmarshaller = new ApexEventUnmarshaller(inputParameters.getKey(), + engineServiceParameters, inputParameters.getValue()); + unmarshallerMap.put(inputParameters.getKey(), unmarshaller); + unmarshaller.init(engineServiceHandler); + } + } - LOGGER.debug("Apex engine started as a service"); + private void instantiateEngine(ApexParameters apexParameters) throws ApexException { + if (null != apexEngineService + && apexEngineService.getKey().equals(apexParameters.getEngineServiceParameters().getEngineKey())) { + throw new ApexException("Apex Engine already initialized."); + } + // Create engine with specified thread count + LOGGER.debug("starting apex engine service . . ."); + apexEngineService = EngineServiceImpl.create(apexParameters.getEngineServiceParameters()); + + // Instantiate and start the messaging service for Deployment + LOGGER.debug("starting apex deployment service . . ."); + final EngDepMessagingService engDepService = new EngDepMessagingService(apexEngineService, + apexParameters.getEngineServiceParameters().getDeploymentPort()); + engDepService.start(); + + // Create the engine holder to hold the engine's references and act as an event receiver + engineServiceHandler = new ApexEngineServiceHandler(apexEngineService, engDepService); } /** @@ -143,10 +213,10 @@ public class ApexActivator { * unmarshalers and marshalers are paired one to one uniquely so if we find a * synchronized unmarshaler we'll also find its * paired marshaler + * @param inputParametersMap the apex parameters */ - private void setUpmarshalerPairings() { - for (final Entry<String, EventHandlerParameters> inputParameters : apexParameters.getEventInputParameters() - .entrySet()) { + private void setUpmarshalerPairings(Map<String, EventHandlerParameters> inputParametersMap) { + for (final Entry<String, EventHandlerParameters> inputParameters : inputParametersMap.entrySet()) { final ApexEventUnmarshaller unmarshaller = unmarshallerMap.get(inputParameters.getKey()); // Pair up peered unmarshalers and marshalers @@ -193,13 +263,4 @@ public class ApexActivator { ModelService.clear(); ParameterService.clear(); } - - /** - * Get the parameters used by the adapter. - * - * @return the parameters of the adapter - */ - public ApexParameters getApexParameters() { - return apexParameters; - } } diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/main/ApexMain.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/main/ApexMain.java index 3bf842c92..4600690e7 100644 --- a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/main/ApexMain.java +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/main/ApexMain.java @@ -23,6 +23,8 @@ package org.onap.policy.apex.service.engine.main; import java.util.Arrays; import java.util.Base64; +import java.util.LinkedHashMap; +import java.util.Map; import java.util.Map.Entry; import lombok.Getter; import lombok.Setter; @@ -30,6 +32,7 @@ import org.onap.policy.apex.model.basicmodel.concepts.ApexException; import org.onap.policy.apex.service.parameters.ApexParameterHandler; import org.onap.policy.apex.service.parameters.ApexParameters; import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifier; import org.slf4j.ext.XLogger; import org.slf4j.ext.XLoggerFactory; @@ -39,13 +42,16 @@ import org.slf4j.ext.XLoggerFactory; * @author Liam Fallon (liam.fallon@ericsson.com) */ public class ApexMain { + private static final String APEX_SERVICE_FAILED_MSG = "start of Apex service failed"; + private static final XLogger LOGGER = XLoggerFactory.getXLogger(ApexMain.class); // The Apex Activator that activates the Apex engine private ApexActivator activator; - // The parameters read in from JSON - private ApexParameters parameters; + // The parameters read in from JSON for each policy + @Getter + private Map<ToscaPolicyIdentifier, ApexParameters> apexParametersMap; @Getter @Setter(lombok.AccessLevel.PRIVATE) @@ -54,11 +60,75 @@ public class ApexMain { /** * Instantiates the Apex service. * - * @param args the commaind line arguments + * @param args the command line arguments */ public ApexMain(final String[] args) { LOGGER.entry("Starting Apex service with parameters " + Arrays.toString(args) + " . . ."); + apexParametersMap = new LinkedHashMap<>(); + try { + apexParametersMap.put(new ToscaPolicyIdentifier(), populateApexParameters(args)); + } catch (ApexException e) { + LOGGER.error(APEX_SERVICE_FAILED_MSG, e); + return; + } + + // Now, create the activator for the Apex service + activator = new ApexActivator(apexParametersMap); + + // Start the activator + try { + activator.initialize(); + setAlive(true); + } catch (final ApexActivatorException e) { + LOGGER.error("start of Apex service failed, used parameters are " + Arrays.toString(args), e); + return; + } + + // Add a shutdown hook to shut everything down in an orderly manner + Runtime.getRuntime().addShutdownHook(new ApexMainShutdownHookClass()); + LOGGER.exit("Started Apex"); + } + /** + * Instantiates the Apex service for multiple policies. + * + * @param policyArgumentsMap the map with command line arguments as value and policy-id as key + * @throws ApexException on errors + */ + public ApexMain(Map<ToscaPolicyIdentifier, String[]> policyArgumentsMap) throws ApexException { + apexParametersMap = new LinkedHashMap<>(); + for ( Entry<ToscaPolicyIdentifier, String[]> policyArgsEntry: policyArgumentsMap.entrySet()) { + try { + apexParametersMap.put(policyArgsEntry.getKey(), populateApexParameters(policyArgsEntry.getValue())); + } catch (ApexException e) { + LOGGER.error("Invalid arguments specified for policy - " + policyArgsEntry.getKey().getName() + ":" + + policyArgsEntry.getKey().getVersion(), e); + } + } + if (apexParametersMap.isEmpty()) { + LOGGER.error(APEX_SERVICE_FAILED_MSG); + return; + } + // Now, create the activator for the Apex service + activator = new ApexActivator(apexParametersMap); + + // Start the activator + try { + activator.initialize(); + apexParametersMap = activator.getApexParametersMap(); + setAlive(true); + } catch (final ApexActivatorException e) { + LOGGER.error(APEX_SERVICE_FAILED_MSG, e); + activator.terminate(); + return; + } + + // Add a shutdown hook to shut everything down in an orderly manner + Runtime.getRuntime().addShutdownHook(new ApexMainShutdownHookClass()); + LOGGER.exit("Started Apex"); + } + + private ApexParameters populateApexParameters(String[] args) throws ApexException { // Check the arguments final ApexCommandLineArguments arguments = new ApexCommandLineArguments(); try { @@ -66,65 +136,46 @@ public class ApexMain { final String argumentMessage = arguments.parse(args); if (argumentMessage != null) { LOGGER.info(argumentMessage); - return; + throw new ApexException(argumentMessage); } // Validate that the arguments are sane arguments.validate(); } catch (final ApexException e) { - LOGGER.error("start of Apex service failed", e); - return; + LOGGER.error("Arguments validation failed.", e); + throw new ApexException("Arguments validation failed.", e); } + ApexParameters axParameters; // Read the parameters try { - parameters = new ApexParameterHandler().getParameters(arguments); + ApexParameterHandler apexParameterHandler = new ApexParameterHandler(); + // In case of multiple policies received from PAP, do not clear ParameterService if parameters of one policy + // already registered + apexParameterHandler.setKeepParameterServiceFlag(null != apexParametersMap && !apexParametersMap.isEmpty()); + axParameters = apexParameterHandler.getParameters(arguments); } catch (final Exception e) { - LOGGER.error("start of Apex service failed", e); - return; + LOGGER.error("Cannot create APEX Parameters from the arguments provided.", e); + throw new ApexException("Cannot create APEX Parameters from the arguments provided.", e); } // Set incoming Java properties - setJavaProperties(parameters); + setJavaProperties(axParameters); // Set the name of the event handler parameters for producers and consumers - for (final Entry<String, EventHandlerParameters> ehParameterEntry : parameters.getEventOutputParameters() + for (final Entry<String, EventHandlerParameters> ehParameterEntry : axParameters.getEventOutputParameters() .entrySet()) { if (!ehParameterEntry.getValue().checkSetName()) { ehParameterEntry.getValue().setName(ehParameterEntry.getKey()); } } - for (final Entry<String, EventHandlerParameters> ehParameterEntry : parameters.getEventInputParameters() + for (final Entry<String, EventHandlerParameters> ehParameterEntry : axParameters.getEventInputParameters() .entrySet()) { if (!ehParameterEntry.getValue().checkSetName()) { ehParameterEntry.getValue().setName(ehParameterEntry.getKey()); } } - - // Now, create the activator for the Apex service - activator = new ApexActivator(parameters); - - // Start the activator - try { - activator.initialize(); - setAlive(true); - } catch (final ApexActivatorException e) { - LOGGER.error("start of Apex service failed, used parameters are " + Arrays.toString(args), e); - return; - } - - // Add a shutdown hook to shut everything down in an orderly manner - Runtime.getRuntime().addShutdownHook(new ApexMainShutdownHookClass()); - LOGGER.exit("Started Apex"); - } - - /** - * Get the parameters specified in JSON. - * - * @return the parameters - */ - public ApexParameters getParameters() { - return parameters; + return axParameters; } /** diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/runtime/impl/EngineServiceImpl.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/runtime/impl/EngineServiceImpl.java index e9edd40e2..152425711 100644 --- a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/runtime/impl/EngineServiceImpl.java +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/runtime/impl/EngineServiceImpl.java @@ -1,19 +1,20 @@ /*- * ============LICENSE_START======================================================= * Copyright (C) 2016-2018 Ericsson. All rights reserved. + * Modifications Copyright (C) 2019 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * * SPDX-License-Identifier: Apache-2.0 * ============LICENSE_END========================================================= */ @@ -28,7 +29,6 @@ import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; - import org.onap.policy.apex.context.ContextException; import org.onap.policy.apex.core.infrastructure.threading.ApplicationThreadFactory; import org.onap.policy.apex.core.infrastructure.threading.ThreadUtilities; @@ -134,13 +134,13 @@ public final class EngineServiceImpl implements EngineService, EngineServiceEven LOGGER.warn("Engine service configuration parameters is null"); throw new ApexException("engine service configuration parameters are null"); } - + final GroupValidationResult validation = config.validate(); if (!validation.isValid()) { LOGGER.warn("Invalid engine service configuration parameters: {}" + validation.getResult()); throw new ApexException("Invalid engine service configuration parameters: " + validation); } - + final AxArtifactKey engineServiceKey = config.getEngineKey(); final int threadCount = config.getInstanceCount(); @@ -235,6 +235,24 @@ public final class EngineServiceImpl implements EngineService, EngineServiceEven @Override public void updateModel(final AxArtifactKey incomingEngineServiceKey, final String apexModelString, final boolean forceFlag) throws ApexException { + AxPolicyModel apexPolicyModel = createModel(incomingEngineServiceKey, apexModelString); + + // Update the model + updateModel(incomingEngineServiceKey, apexPolicyModel, forceFlag); + + LOGGER.exit(); + } + + /** + * Method to create model. + * + * @param incomingEngineServiceKey incoming engine service key + * @param apexModelString apex model string + * @return apexPolicyModel the policy model + * @throws ApexException apex exception + */ + public static AxPolicyModel createModel(final AxArtifactKey incomingEngineServiceKey, final String apexModelString) + throws ApexException { // Check if the engine service key specified is sane if (incomingEngineServiceKey == null) { String message = ENGINE_KEY_NOT_SPECIFIED; @@ -260,11 +278,7 @@ public final class EngineServiceImpl implements EngineService, EngineServiceEven LOGGER.error(message, e); throw new ApexException(message, e); } - - // Update the model - updateModel(incomingEngineServiceKey, apexPolicyModel, forceFlag); - - LOGGER.exit(); + return apexPolicyModel; } /** @@ -314,7 +328,7 @@ public final class EngineServiceImpl implements EngineService, EngineServiceEven /** * Execute the model update on the engine instances. - * + * * @param incomingEngineServiceKey the engine service key to update * @param apexModel the model to update the engines with * @param forceFlag if true, ignore compatibility problems @@ -322,7 +336,7 @@ public final class EngineServiceImpl implements EngineService, EngineServiceEven */ private void executeModelUpdate(final AxArtifactKey incomingEngineServiceKey, final AxPolicyModel apexModel, final boolean forceFlag) throws ApexException { - + if (!isStopped()) { stopEngines(incomingEngineServiceKey); } @@ -458,7 +472,7 @@ public final class EngineServiceImpl implements EngineService, EngineServiceEven // Start the engine engineWorkerMap.get(engineKey).start(engineKey); - + // Check if periodic events should be turned on if (periodicEventPeriod > 0) { startPeriodicEvents(periodicEventPeriod); @@ -478,7 +492,7 @@ public final class EngineServiceImpl implements EngineService, EngineServiceEven periodicEventGenerator.cancel(); periodicEventGenerator = null; } - + // Stop each engine for (final EngineService engine : engineWorkerMap.values()) { if (engine.getState() != AxEngineState.STOPPED) { diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/ApexParameterHandler.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/ApexParameterHandler.java index 4312793e4..c1ef50bd7 100644 --- a/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/ApexParameterHandler.java +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/ApexParameterHandler.java @@ -1,6 +1,7 @@ /*- * ============LICENSE_START======================================================= * Copyright (C) 2016-2018 Ericsson. All rights reserved. + * Modifications Copyright (C) 2019 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,9 +23,8 @@ package org.onap.policy.apex.service.parameters; import com.google.gson.Gson; import com.google.gson.GsonBuilder; - import java.io.FileReader; - +import lombok.Setter; import org.onap.policy.apex.core.engine.EngineParameters; import org.onap.policy.apex.service.engine.main.ApexCommandLineArguments; import org.onap.policy.apex.service.parameters.carriertechnology.CarrierTechnologyParameters; @@ -46,6 +46,9 @@ import org.slf4j.ext.XLoggerFactory; public class ApexParameterHandler { private static final XLogger LOGGER = XLoggerFactory.getXLogger(ApexParameterHandler.class); + @Setter + private boolean keepParameterServiceFlag; + /** * Read the parameters from the parameter file. * @@ -54,8 +57,11 @@ public class ApexParameterHandler { * @throws ParameterException on parameter exceptions */ public ApexParameters getParameters(final ApexCommandLineArguments arguments) throws ParameterException { - // Clear all existing parameters - ParameterService.clear(); + // when populating parameters for multiple policies, do not clear the ParameterService already registered + // otherwise clear all existing parameters + if (!keepParameterServiceFlag) { + ParameterService.clear(); + } ApexParameters parameters = null; @@ -112,8 +118,12 @@ public class ApexParameterHandler { LOGGER.info(returnMessage); } - // Register the parameters with the parameter service - registerParameters(parameters); + // engine parameters in multiple policies are expected to be same. + // no need to do registration if already registered + if (!keepParameterServiceFlag) { + // Register the parameters with the parameter service + registerParameters(parameters); + } return parameters; } diff --git a/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/main/ApexMainTest.java b/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/main/ApexMainTest.java index 6ed3c755d..86ae99ec7 100644 --- a/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/main/ApexMainTest.java +++ b/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/main/ApexMainTest.java @@ -5,15 +5,15 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * * SPDX-License-Identifier: Apache-2.0 * ============LICENSE_END========================================================= */ @@ -26,10 +26,14 @@ import static org.junit.Assert.assertTrue; import java.io.ByteArrayOutputStream; import java.io.OutputStream; import java.io.PrintStream; - +import java.util.HashMap; +import java.util.Map; +import org.junit.After; import org.junit.Test; import org.onap.policy.apex.core.infrastructure.threading.ThreadUtilities; import org.onap.policy.apex.model.basicmodel.concepts.ApexException; +import org.onap.policy.apex.service.parameters.ApexParameters; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifier; /** * Test the ApexMain class. @@ -37,6 +41,16 @@ import org.onap.policy.apex.model.basicmodel.concepts.ApexException; public class ApexMainTest { private PrintStream stdout = System.out; + /** + * Method for cleanup after each test. + * + * @throws Exception if an error occurs + */ + @After + public void teardown() throws Exception { + System.setOut(stdout); + } + @Test public void testNullParameters() throws ApexException { OutputStream outContent = new ByteArrayOutputStream(); @@ -47,8 +61,6 @@ public class ApexMainTest { final String outString = outContent.toString(); - System.setOut(stdout); - assertTrue(outString.contains("Apex configuration file was not specified as an argument")); } @@ -65,8 +77,6 @@ public class ApexMainTest { final String outString = outContent.toString(); - System.setOut(stdout); - assertTrue(outString.contains("invalid command line arguments specified : Unrecognized option: -whee")); } @@ -83,8 +93,6 @@ public class ApexMainTest { final String outString = outContent.toString(); - System.setOut(stdout); - assertTrue(outString.contains("usage: org.onap.policy.apex.service.engine.main.ApexMain [options...]")); } @@ -101,8 +109,6 @@ public class ApexMainTest { final String outString = outContent.toString(); - System.setOut(stdout); - assertTrue(outString.contains("parameter group has status INVALID")); } @@ -114,14 +120,13 @@ public class ApexMainTest { String[] args = { "-c", "src/test/resources/parameters/correctParams.json" }; final ApexMain apexMain = new ApexMain(args); - assertEquals("MyApexEngine", apexMain.getParameters().getEngineServiceParameters().getName()); + assertEquals("MyApexEngine", + apexMain.getApexParametersMap().values().iterator().next().getEngineServiceParameters().getName()); ThreadUtilities.sleep(200); apexMain.shutdown(); final String outString = outContent.toString(); - System.setOut(stdout); - assertTrue(outString.contains("Added the action listener to the engine")); } @@ -133,7 +138,8 @@ public class ApexMainTest { String[] args = { "-c", "src/test/resources/parameters/correctParamsJavaProperties.json" }; final ApexMain apexMain = new ApexMain(args); - assertEquals("MyApexEngine", apexMain.getParameters().getEngineServiceParameters().getName()); + assertEquals("MyApexEngine", + apexMain.getApexParametersMap().values().iterator().next().getEngineServiceParameters().getName()); assertEquals("trust-store-file", System.getProperty("javax.net.ssl.trustStore")); assertEquals("Pol1cy_0nap", System.getProperty("javax.net.ssl.trustStorePassword")); @@ -143,8 +149,55 @@ public class ApexMainTest { ThreadUtilities.sleep(10000); final String outString = outContent.toString(); - System.setOut(stdout); + assertTrue(outString.contains("Added the action listener to the engine")); + } + @Test + public void testCorrectParametersWithMultiplePolicies() throws ApexException { + OutputStream outContent = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outContent)); + Map<ToscaPolicyIdentifier, String[]> argsMap = new HashMap<ToscaPolicyIdentifier, String[]>(); + String[] args = {"-c", "src/test/resources/parameters/correctParams.json", "-m", + "src/test/resources/policymodels/SmallModel.json"}; + argsMap.put(new ToscaPolicyIdentifier("id1", "v1"), args); + final ApexMain apexMain = new ApexMain(argsMap); + ApexParameters apexParam = (ApexParameters) apexMain.getApexParametersMap().values().toArray()[0]; + assertEquals("MyApexEngine", apexParam.getEngineServiceParameters().getName()); + apexMain.shutdown(); + final String outString = outContent.toString(); assertTrue(outString.contains("Added the action listener to the engine")); } + + @Test + public void testInCorrectParametersWithMultiplePolicies() throws ApexException { + OutputStream outContent = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outContent)); + Map<ToscaPolicyIdentifier, String[]> argsMap = new HashMap<ToscaPolicyIdentifier, String[]>(); + String[] args = {"-c", "src/test/resources/parameters/correctParams.json", "-m", + "src/test/resources/policymodels/SmallModel.json"}; + argsMap.put(new ToscaPolicyIdentifier("id1", "v1"), args); + argsMap.put(new ToscaPolicyIdentifier("id2", "v2"), args); + final ApexMain apexMain = new ApexMain(argsMap); + ApexParameters apexParam = (ApexParameters) apexMain.getApexParametersMap().values().toArray()[0]; + assertEquals("MyApexEngine", apexParam.getEngineServiceParameters().getName()); + apexMain.shutdown(); + final String outString = outContent.toString(); + assertTrue(outString.contains("I/O Parameters for id2:v2 has duplicates. So this policy is not executed")); + assertTrue(apexMain.getApexParametersMap().size() == 1); // only id1:v1 is kept in the map, id2:v2 failed + } + + @Test + public void testInvalidArgsWithMultiplePolicies() throws ApexException { + OutputStream outContent = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outContent)); + Map<ToscaPolicyIdentifier, String[]> argsMap = new HashMap<ToscaPolicyIdentifier, String[]>(); + String[] args = {"-c", "file1", "-m", "file2"}; + argsMap.put(new ToscaPolicyIdentifier("id1", "v1"), args); + final ApexMain apexMain = new ApexMain(argsMap); + final String outString = outContent.toString(); + apexMain.shutdown(); + assertTrue( + outString.contains("Arguments validation failed") && outString.contains("start of Apex service failed")); + assertTrue(apexMain.getApexParametersMap().isEmpty()); // No policy is running in the engine + } } diff --git a/services/services-onappf/src/main/java/org/onap/policy/apex/services/onappf/handler/ApexEngineHandler.java b/services/services-onappf/src/main/java/org/onap/policy/apex/services/onappf/handler/ApexEngineHandler.java index 4f68b90ae..1953939b7 100644 --- a/services/services-onappf/src/main/java/org/onap/policy/apex/services/onappf/handler/ApexEngineHandler.java +++ b/services/services-onappf/src/main/java/org/onap/policy/apex/services/onappf/handler/ApexEngineHandler.java @@ -21,17 +21,21 @@ package org.onap.policy.apex.services.onappf.handler; import com.google.gson.JsonObject; - import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; - +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; import org.onap.policy.apex.model.basicmodel.concepts.ApexException; import org.onap.policy.apex.service.engine.main.ApexMain; import org.onap.policy.apex.services.onappf.exception.ApexStarterException; import org.onap.policy.common.utils.coder.CoderException; import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -46,31 +50,41 @@ public class ApexEngineHandler { private ApexMain apexMain; /** - * Constructs the object. Extracts the apex config and model files and instantiates the apex engine. + * Constructs the object. Extracts the config and model files from each policy and instantiates the apex engine. * - * @param properties the properties which contains the policies and configurations received from pap - * @throws ApexStarterException if the apex engine instantiation failed using the properties passed + * @param policies the list of policies + * @throws ApexStarterException if the apex engine instantiation failed using the policies passed */ - public ApexEngineHandler(final Object properties) throws ApexStarterException { - final StandardCoder standardCoder = new StandardCoder(); - String policyModel; - String apexConfig; - try { - JsonObject body = standardCoder.decode(standardCoder.encode(properties), JsonObject.class); - final JsonObject engineServiceParameters = body.get("engineServiceParameters").getAsJsonObject(); - policyModel = standardCoder.encode(engineServiceParameters.get("policy_type_impl")); - engineServiceParameters.remove("policy_type_impl"); - apexConfig = standardCoder.encode(body); - } catch (final CoderException e) { - throw new ApexStarterException(e); - } + public ApexEngineHandler(List<ToscaPolicy> policies) throws ApexStarterException { + Map<ToscaPolicyIdentifier, String[]> policyArgsMap = new LinkedHashMap<>(); + for (ToscaPolicy policy : policies) { + Object properties = policy.getProperties().get("content"); + final StandardCoder standardCoder = new StandardCoder(); + String policyModel; + String apexConfig; + try { + JsonObject body = standardCoder.decode(standardCoder.encode(properties), JsonObject.class); + final JsonObject engineServiceParameters = body.get("engineServiceParameters").getAsJsonObject(); + policyModel = standardCoder.encode(engineServiceParameters.get("policy_type_impl")); + engineServiceParameters.remove("policy_type_impl"); + apexConfig = standardCoder.encode(body); + } catch (final CoderException e) { + throw new ApexStarterException(e); + } + + final String modelFilePath = createFile(policyModel, "modelFile"); - final String modelFilePath = createFile(policyModel, "modelFile"); + final String apexConfigFilePath = createFile(apexConfig, "apexConfigFile"); + final String[] apexArgs = { "-c", apexConfigFilePath, "-m", modelFilePath }; + policyArgsMap.put(policy.getIdentifier(), apexArgs); + } - final String apexConfigFilePath = createFile(apexConfig, "apexConfigFile"); - final String[] apexArgs = { "-c", apexConfigFilePath, "-m", modelFilePath }; LOGGER.debug("Starting apex engine."); - apexMain = new ApexMain(apexArgs); + try { + apexMain = new ApexMain(policyArgsMap); + } catch (ApexException e) { + throw new ApexStarterException(e); + } } /** @@ -100,6 +114,13 @@ public class ApexEngineHandler { } /** + * Method that return the list of running policies in the apex engine. + */ + public List<ToscaPolicyIdentifier> getRunningPolicies() { + return new ArrayList<>(apexMain.getApexParametersMap().keySet()); + } + + /** * Method to shut down the apex engine. */ public void shutdown() throws ApexStarterException { diff --git a/services/services-onappf/src/main/java/org/onap/policy/apex/services/onappf/handler/PdpStateChangeMessageHandler.java b/services/services-onappf/src/main/java/org/onap/policy/apex/services/onappf/handler/PdpStateChangeMessageHandler.java index 8658150c0..fd95b47b7 100644 --- a/services/services-onappf/src/main/java/org/onap/policy/apex/services/onappf/handler/PdpStateChangeMessageHandler.java +++ b/services/services-onappf/src/main/java/org/onap/policy/apex/services/onappf/handler/PdpStateChangeMessageHandler.java @@ -20,6 +20,7 @@ package org.onap.policy.apex.services.onappf.handler; +import java.util.HashSet; import java.util.List; import org.onap.policy.apex.services.onappf.ApexStarterConstants; import org.onap.policy.apex.services.onappf.comm.PdpStatusPublisher; @@ -31,6 +32,7 @@ import org.onap.policy.models.pdp.concepts.PdpStatus; import org.onap.policy.models.pdp.enums.PdpResponseStatus; import org.onap.policy.models.pdp.enums.PdpState; import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -93,25 +95,55 @@ public class PdpStateChangeMessageHandler { pdpResponseDetails = pdpMessageHandler.createPdpResonseDetails(pdpStateChangeMsg.getRequestId(), PdpResponseStatus.SUCCESS, "State changed to active. No policies found."); } else { - try { - // assumed that the apex policies list contains only one entry. - final ApexEngineHandler apexEngineHandler = - new ApexEngineHandler(policies.get(0).getProperties().get("content")); - Registry.registerOrReplace(ApexStarterConstants.REG_APEX_ENGINE_HANDLER, apexEngineHandler); - if (apexEngineHandler.isApexEngineRunning()) { - pdpResponseDetails = pdpMessageHandler.createPdpResonseDetails(pdpStateChangeMsg.getRequestId(), + pdpResponseDetails = startApexEngine(pdpStateChangeMsg, pdpStatusContext, pdpMessageHandler, policies); + } + } + return pdpResponseDetails; + } + + /** + * Method to start apex engine. + * + * @param pdpStateChangeMsg pdp state change message + * @param pdpStatusContext pdp status in memory + * @param pdpMessageHandler the pdp message handler + * @param policies list of policies + * @return pdp response details + */ + private PdpResponseDetails startApexEngine(final PdpStateChange pdpStateChangeMsg, final PdpStatus pdpStatusContext, + final PdpMessageHandler pdpMessageHandler, final List<ToscaPolicy> policies) { + PdpResponseDetails pdpResponseDetails; + try { + final ApexEngineHandler apexEngineHandler = new ApexEngineHandler(policies); + Registry.registerOrReplace(ApexStarterConstants.REG_APEX_ENGINE_HANDLER, apexEngineHandler); + if (apexEngineHandler.isApexEngineRunning()) { + List<ToscaPolicyIdentifier> runningPolicies = apexEngineHandler.getRunningPolicies(); + // only the policies which are succesfully executed should be there in the heartbeat + pdpStatusContext.setPolicies(runningPolicies); + if (new HashSet<>(runningPolicies) + .equals(new HashSet<>(pdpMessageHandler.getToscaPolicyIdentifiers(policies)))) { + pdpResponseDetails = + pdpMessageHandler.createPdpResonseDetails(pdpStateChangeMsg.getRequestId(), PdpResponseStatus.SUCCESS, "Apex engine started. State changed to active."); - pdpStatusContext.setState(PdpState.ACTIVE); - } else { - pdpResponseDetails = pdpMessageHandler.createPdpResonseDetails(pdpStateChangeMsg.getRequestId(), - PdpResponseStatus.FAIL, "Apex engine failed to start. State cannot be changed to active."); + } else { + StringBuilder message = new StringBuilder( + "Apex engine started. But, only the following polices are running - "); + for (ToscaPolicyIdentifier policy : runningPolicies) { + message.append(policy.getName()).append(":").append(policy.getVersion()).append(" "); } - } catch (final ApexStarterException e) { - LOGGER.error("Pdp update failed as the policies couldn't be undeployed.", e); - pdpResponseDetails = pdpMessageHandler.createPdpResonseDetails(pdpStateChangeMsg.getRequestId(), - PdpResponseStatus.FAIL, "Apex engine service running failed. " + e.getMessage()); + message.append(". Other policies failed execution. Please see the logs for more details."); + pdpResponseDetails = pdpMessageHandler.createPdpResonseDetails( + pdpStateChangeMsg.getRequestId(), PdpResponseStatus.SUCCESS, message.toString()); } + pdpStatusContext.setState(PdpState.ACTIVE); + } else { + pdpResponseDetails = pdpMessageHandler.createPdpResonseDetails(pdpStateChangeMsg.getRequestId(), + PdpResponseStatus.FAIL, "Apex engine failed to start. State cannot be changed to active."); } + } catch (final ApexStarterException e) { + LOGGER.error("Pdp State Change failed.", e); + pdpResponseDetails = pdpMessageHandler.createPdpResonseDetails(pdpStateChangeMsg.getRequestId(), + PdpResponseStatus.FAIL, "Apex engine service running failed. " + e.getMessage()); } return pdpResponseDetails; } diff --git a/services/services-onappf/src/main/java/org/onap/policy/apex/services/onappf/handler/PdpUpdateMessageHandler.java b/services/services-onappf/src/main/java/org/onap/policy/apex/services/onappf/handler/PdpUpdateMessageHandler.java index d807dc50e..ecc0bec21 100644 --- a/services/services-onappf/src/main/java/org/onap/policy/apex/services/onappf/handler/PdpUpdateMessageHandler.java +++ b/services/services-onappf/src/main/java/org/onap/policy/apex/services/onappf/handler/PdpUpdateMessageHandler.java @@ -20,6 +20,8 @@ package org.onap.policy.apex.services.onappf.handler; +import java.util.Collections; +import java.util.HashSet; import java.util.List; import org.onap.policy.apex.services.onappf.ApexStarterConstants; import org.onap.policy.apex.services.onappf.comm.PdpStatusPublisher; @@ -31,6 +33,7 @@ import org.onap.policy.models.pdp.concepts.PdpStatus; import org.onap.policy.models.pdp.concepts.PdpUpdate; import org.onap.policy.models.pdp.enums.PdpResponseStatus; 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; @@ -54,27 +57,11 @@ public class PdpUpdateMessageHandler { PdpResponseDetails pdpResponseDetails = null; if (pdpUpdateMsg.appliesTo(pdpStatusContext.getName(), pdpStatusContext.getPdpGroup(), pdpStatusContext.getPdpSubgroup())) { - final PdpStatusPublisher pdpStatusPublisher = Registry.get(ApexStarterConstants.REG_PDP_STATUS_PUBLISHER); if (checkIfAlreadyHandled(pdpUpdateMsg, pdpStatusContext)) { pdpResponseDetails = pdpMessageHandler.createPdpResonseDetails(pdpUpdateMsg.getRequestId(), PdpResponseStatus.SUCCESS, "Pdp already updated"); } else { - if (null != pdpUpdateMsg.getPdpHeartbeatIntervalMs() && pdpUpdateMsg.getPdpHeartbeatIntervalMs() > 0 - && pdpStatusPublisher.getInterval() != pdpUpdateMsg.getPdpHeartbeatIntervalMs()) { - updateInterval(pdpUpdateMsg.getPdpHeartbeatIntervalMs()); - } - pdpStatusContext.setPdpGroup(pdpUpdateMsg.getPdpGroup()); - pdpStatusContext.setPdpSubgroup(pdpUpdateMsg.getPdpSubgroup()); - pdpStatusContext - .setPolicies(new PdpMessageHandler().getToscaPolicyIdentifiers(pdpUpdateMsg.getPolicies())); - if (pdpStatusContext.getState().equals(PdpState.ACTIVE)) { - pdpResponseDetails = startOrStopApexEngineBasedOnPolicies(pdpUpdateMsg, pdpMessageHandler); - } - Registry.registerOrReplace(ApexStarterConstants.REG_APEX_TOSCA_POLICY_LIST, pdpUpdateMsg.getPolicies()); - if (null == pdpResponseDetails) { - pdpResponseDetails = pdpMessageHandler.createPdpResonseDetails(pdpUpdateMsg.getRequestId(), - PdpResponseStatus.SUCCESS, "Pdp update successful."); - } + pdpResponseDetails = handlePdpUpdate(pdpUpdateMsg, pdpMessageHandler, pdpStatusContext); } final PdpStatusPublisher pdpStatusPublisherTemp = Registry.get(ApexStarterConstants.REG_PDP_STATUS_PUBLISHER); @@ -86,6 +73,47 @@ public class PdpUpdateMessageHandler { } /** + * Method to do pdp update. + * + * @param pdpUpdateMsg the pdp update message + * @param pdpMessageHandler the message handler + * @param pdpStatusContext the pdp status in memory + * @return pdpResponseDetails the pdp response + */ + private PdpResponseDetails handlePdpUpdate(final PdpUpdate pdpUpdateMsg, final PdpMessageHandler pdpMessageHandler, + final PdpStatus pdpStatusContext) { + PdpResponseDetails pdpResponseDetails = null; + final PdpStatusPublisher pdpStatusPublisher = Registry.get(ApexStarterConstants.REG_PDP_STATUS_PUBLISHER); + if (null != pdpUpdateMsg.getPdpHeartbeatIntervalMs() && pdpUpdateMsg.getPdpHeartbeatIntervalMs() > 0 + && pdpStatusPublisher.getInterval() != pdpUpdateMsg.getPdpHeartbeatIntervalMs()) { + updateInterval(pdpUpdateMsg.getPdpHeartbeatIntervalMs()); + } + pdpStatusContext.setPdpGroup(pdpUpdateMsg.getPdpGroup()); + pdpStatusContext.setPdpSubgroup(pdpUpdateMsg.getPdpSubgroup()); + pdpStatusContext + .setPolicies(new PdpMessageHandler().getToscaPolicyIdentifiers(pdpUpdateMsg.getPolicies())); + Registry.registerOrReplace(ApexStarterConstants.REG_APEX_TOSCA_POLICY_LIST, pdpUpdateMsg.getPolicies()); + if (pdpStatusContext.getState().equals(PdpState.ACTIVE)) { + pdpResponseDetails = startOrStopApexEngineBasedOnPolicies(pdpUpdateMsg, pdpMessageHandler); + + ApexEngineHandler apexEngineHandler = Registry.get(ApexStarterConstants.REG_APEX_ENGINE_HANDLER); + // in hearbeat while in active state, only the policies which are running should be there. + // if some policy fails, that shouldn't go in the heartbeat. + // If no policies are running, then the policy list in the heartbeat can be empty + if (null != apexEngineHandler && apexEngineHandler.isApexEngineRunning()) { + pdpStatusContext.setPolicies(apexEngineHandler.getRunningPolicies()); + } else { + pdpStatusContext.setPolicies(Collections.emptyList()); + } + } + if (null == pdpResponseDetails) { + pdpResponseDetails = pdpMessageHandler.createPdpResonseDetails(pdpUpdateMsg.getRequestId(), + PdpResponseStatus.SUCCESS, "Pdp update successful."); + } + return pdpResponseDetails; + } + + /** * Method to start or stop apex engine based on the list of policies received from pap. When current state is * active, if PAP sends PdpUpdate with empty policies list, stop apex engine, or, if there is a change in policies, * stop the current running policies and the deploy the new ones. @@ -118,6 +146,8 @@ public class PdpUpdateMessageHandler { if (null != apexEngineHandler && apexEngineHandler.isApexEngineRunning()) { try { apexEngineHandler.shutdown(); + pdpResponseDetails = pdpMessageHandler.createPdpResonseDetails(pdpUpdateMsg.getRequestId(), + PdpResponseStatus.SUCCESS, "Pdp update successful. No policies are running."); } catch (final ApexStarterException e) { LOGGER.error("Pdp update failed as the policies couldn't be undeployed.", e); pdpResponseDetails = pdpMessageHandler.createPdpResonseDetails(pdpUpdateMsg.getRequestId(), @@ -134,12 +164,24 @@ public class PdpUpdateMessageHandler { if (null != apexEngineHandler && apexEngineHandler.isApexEngineRunning()) { apexEngineHandler.shutdown(); } - apexEngineHandler = - new ApexEngineHandler(pdpUpdateMsg.getPolicies().get(0).getProperties().get("content")); + apexEngineHandler = new ApexEngineHandler(pdpUpdateMsg.getPolicies()); Registry.registerOrReplace(ApexStarterConstants.REG_APEX_ENGINE_HANDLER, apexEngineHandler); if (apexEngineHandler.isApexEngineRunning()) { - pdpResponseDetails = pdpMessageHandler.createPdpResonseDetails(pdpUpdateMsg.getRequestId(), - PdpResponseStatus.SUCCESS, "Apex engine started and policies are running."); + List<ToscaPolicyIdentifier> runningPolicies = apexEngineHandler.getRunningPolicies(); + if (new HashSet<>(runningPolicies) + .equals(new HashSet<>(pdpMessageHandler.getToscaPolicyIdentifiers(pdpUpdateMsg.getPolicies())))) { + pdpResponseDetails = pdpMessageHandler.createPdpResonseDetails(pdpUpdateMsg.getRequestId(), + PdpResponseStatus.SUCCESS, "Apex engine started and policies are running."); + } else { + StringBuilder message = + new StringBuilder("Apex engine started. But, only the following polices are running - "); + for (ToscaPolicyIdentifier policy : runningPolicies) { + message.append(policy.getName()).append(":").append(policy.getVersion()).append(" "); + } + message.append(". Other policies failed execution. Please see the logs for more details."); + pdpResponseDetails = pdpMessageHandler.createPdpResonseDetails(pdpUpdateMsg.getRequestId(), + PdpResponseStatus.SUCCESS, message.toString()); + } } else { pdpResponseDetails = pdpMessageHandler.createPdpResonseDetails(pdpUpdateMsg.getRequestId(), PdpResponseStatus.FAIL, "Apex engine failed to start."); diff --git a/services/services-onappf/src/test/java/org/onap/policy/apex/services/onappf/TestApexStarterActivator.java b/services/services-onappf/src/test/java/org/onap/policy/apex/services/onappf/TestApexStarterActivator.java index c8f889fde..77ffa5317 100644 --- a/services/services-onappf/src/test/java/org/onap/policy/apex/services/onappf/TestApexStarterActivator.java +++ b/services/services-onappf/src/test/java/org/onap/policy/apex/services/onappf/TestApexStarterActivator.java @@ -56,7 +56,7 @@ public class TestApexStarterActivator { @Before public void setUp() throws Exception { Registry.newRegistry(); - final String[] apexStarterConfigParameters = { "-c", "src/test/resources/ApexStarterConfigParameters.json"}; + final String[] apexStarterConfigParameters = { "-c", "src/test/resources/ApexStarterConfigParametersNoop.json"}; final ApexStarterCommandLineArguments arguments = new ApexStarterCommandLineArguments(apexStarterConfigParameters); final ApexStarterParameterGroup parGroup = new ApexStarterParameterHandler().getParameters(arguments); diff --git a/services/services-onappf/src/test/java/org/onap/policy/apex/services/onappf/TestApexStarterMain.java b/services/services-onappf/src/test/java/org/onap/policy/apex/services/onappf/TestApexStarterMain.java index 68d30258b..2fcfe886f 100644 --- a/services/services-onappf/src/test/java/org/onap/policy/apex/services/onappf/TestApexStarterMain.java +++ b/services/services-onappf/src/test/java/org/onap/policy/apex/services/onappf/TestApexStarterMain.java @@ -27,9 +27,6 @@ import static org.junit.Assert.assertTrue; import org.junit.After; import org.junit.Before; import org.junit.Test; -import org.onap.policy.apex.services.onappf.ApexStarterActivator; -import org.onap.policy.apex.services.onappf.ApexStarterConstants; -import org.onap.policy.apex.services.onappf.ApexStarterMain; import org.onap.policy.apex.services.onappf.exception.ApexStarterException; import org.onap.policy.apex.services.onappf.parameters.CommonTestData; import org.onap.policy.common.utils.services.Registry; @@ -67,7 +64,7 @@ public class TestApexStarterMain { @Test public void testApexStarter() throws ApexStarterException { - final String[] apexStarterConfigParameters = { "-c", "src/test/resources/ApexStarterConfigParameters.json"}; + final String[] apexStarterConfigParameters = { "-c", "src/test/resources/ApexStarterConfigParametersNoop.json"}; apexStarter = new ApexStarterMain(apexStarterConfigParameters); assertTrue(apexStarter.getParameters().isValid()); assertEquals(CommonTestData.APEX_STARTER_GROUP_NAME, apexStarter.getParameters().getName()); diff --git a/services/services-onappf/src/test/java/org/onap/policy/apex/services/onappf/comm/TestListenerUtils.java b/services/services-onappf/src/test/java/org/onap/policy/apex/services/onappf/comm/TestListenerUtils.java new file mode 100644 index 000000000..78d9d769b --- /dev/null +++ b/services/services-onappf/src/test/java/org/onap/policy/apex/services/onappf/comm/TestListenerUtils.java @@ -0,0 +1,99 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.services.onappf.comm; + +import com.google.gson.JsonObject; +import java.io.File; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +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.PdpState; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; + +public class TestListenerUtils { + + /** + * Method to create PdpUpdate message from the arguments passed. + * + * @param pdpStatus pdp status + * @param toscaPolicies list of tosca policies + * + * @return PdpUpdate message + */ + public static PdpUpdate createPdpUpdateMsg(final PdpStatus pdpStatus, List<ToscaPolicy> toscaPolicies ) { + final PdpUpdate pdpUpdateMsg = new PdpUpdate(); + pdpUpdateMsg.setDescription("dummy pdp status for test"); + pdpUpdateMsg.setPdpGroup("pdpGroup"); + pdpUpdateMsg.setPdpSubgroup("pdpSubgroup"); + pdpUpdateMsg.setName(pdpStatus.getName()); + pdpUpdateMsg.setPdpHeartbeatIntervalMs(Long.valueOf(3000)); + pdpUpdateMsg.setPolicies(toscaPolicies); + return pdpUpdateMsg; + } + + /** + * Method to create ToscaPolicy using the arguments passed. + * + * @param policyName the name of the policy + * @param policyVersion the version of the policy + * @param policyFilePath the path of the policy content + * + * @return PdpUpdate message + * @throws CoderException exception while reading the file to object + */ + public static ToscaPolicy createToscaPolicy(String policyName, String policyVersion, String policyFilePath) + throws CoderException { + final ToscaPolicy toscaPolicy = new ToscaPolicy(); + toscaPolicy.setType("apexpolicytype"); + toscaPolicy.setVersion(policyVersion); + toscaPolicy.setName(policyName); + final Map<String, Object> propertiesMap = new LinkedHashMap<>(); + Object properties = new StandardCoder().decode(new File(policyFilePath), JsonObject.class); + propertiesMap.put("content", properties); + toscaPolicy.setProperties(propertiesMap); + return toscaPolicy; + } + + /** + * Method to create PdpStateChange message from the arguments passed. + * + * @param state the new pdp state + * @param pdpGroup name of the pdpGroup + * @param pdpSubgroup name of the pdpSubGroup + * @param name the name of the message + * + * @return PdpStateChange message + */ + public static PdpStateChange createPdpStateChangeMsg(PdpState state, String pdpGroup, String pdpSubgroup, + String name) { + final PdpStateChange pdpStateChangeMsg = new PdpStateChange(); + pdpStateChangeMsg.setState(state); + pdpStateChangeMsg.setPdpGroup(pdpGroup); + pdpStateChangeMsg.setPdpSubgroup(pdpSubgroup); + pdpStateChangeMsg.setName(name); + return pdpStateChangeMsg; + } +} diff --git a/services/services-onappf/src/test/java/org/onap/policy/apex/services/onappf/comm/TestPdpStateChangeListener.java b/services/services-onappf/src/test/java/org/onap/policy/apex/services/onappf/comm/TestPdpStateChangeListener.java index c475b50ff..7f7de3b42 100644 --- a/services/services-onappf/src/test/java/org/onap/policy/apex/services/onappf/comm/TestPdpStateChangeListener.java +++ b/services/services-onappf/src/test/java/org/onap/policy/apex/services/onappf/comm/TestPdpStateChangeListener.java @@ -23,16 +23,15 @@ package org.onap.policy.apex.services.onappf.comm; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import java.io.ByteArrayOutputStream; import java.io.FileNotFoundException; import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Paths; +import java.io.OutputStream; +import java.io.PrintStream; import java.util.ArrayList; -import java.util.LinkedHashMap; import java.util.List; -import java.util.Map; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -40,9 +39,11 @@ import org.onap.policy.apex.services.onappf.ApexStarterActivator; import org.onap.policy.apex.services.onappf.ApexStarterCommandLineArguments; import org.onap.policy.apex.services.onappf.ApexStarterConstants; import org.onap.policy.apex.services.onappf.exception.ApexStarterException; +import org.onap.policy.apex.services.onappf.handler.ApexEngineHandler; import org.onap.policy.apex.services.onappf.parameters.ApexStarterParameterGroup; import org.onap.policy.apex.services.onappf.parameters.ApexStarterParameterHandler; import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; +import org.onap.policy.common.utils.coder.CoderException; import org.onap.policy.common.utils.services.Registry; import org.onap.policy.models.pdp.concepts.PdpStateChange; import org.onap.policy.models.pdp.concepts.PdpStatus; @@ -61,6 +62,8 @@ public class TestPdpStateChangeListener { private static final CommInfrastructure INFRA = CommInfrastructure.NOOP; private static final String TOPIC = "my-topic"; private ApexStarterActivator activator; + private ApexEngineHandler apexEngineHandler; + private PrintStream stdout = System.out; /** * Method for setup before each test. @@ -74,7 +77,7 @@ public class TestPdpStateChangeListener { pdpUpdateMessageListener = new PdpUpdateListener(); pdpStateChangeListener = new PdpStateChangeListener(); Registry.newRegistry(); - final String[] apexStarterConfigParameters = { "-c", "src/test/resources/ApexStarterConfigParameters.json" }; + final String[] apexStarterConfigParameters = {"-c", "src/test/resources/ApexStarterConfigParametersNoop.json"}; final ApexStarterCommandLineArguments arguments = new ApexStarterCommandLineArguments(); ApexStarterParameterGroup parameterGroup; // The arguments return a string if there is a message to print and we should @@ -101,55 +104,25 @@ public class TestPdpStateChangeListener { */ @After public void teardown() throws Exception { - + System.setOut(stdout); + apexEngineHandler = + Registry.getOrDefault(ApexStarterConstants.REG_APEX_ENGINE_HANDLER, ApexEngineHandler.class, null); + if (null != apexEngineHandler && apexEngineHandler.isApexEngineRunning()) { + apexEngineHandler.shutdown(); + } // clear the apex starter activator if (activator != null && activator.isAlive()) { activator.terminate(); } } - /** - * Method to initiate a PdpUpdate. - * - * @param instance the instance id - * @return PdpUpdate the pdp update message - */ - private PdpUpdate performPdpUpdate(final String instance) { - final PdpUpdate pdpUpdateMsg = new PdpUpdate(); - pdpUpdateMsg.setDescription("dummy pdp status for test"); - pdpUpdateMsg.setPdpGroup("pdpGroup"); - pdpUpdateMsg.setPdpSubgroup("pdpSubgroup"); - pdpUpdateMsg.setName(instance); - final ToscaPolicy toscaPolicy = new ToscaPolicy(); - toscaPolicy.setType("apexpolicytype"); - toscaPolicy.setVersion("1.0"); - final Map<String, Object> propertiesMap = new LinkedHashMap<>(); - - String properties; - try { - properties = new String(Files.readAllBytes(Paths.get("src\\test\\resources\\dummyProperties.json")), - StandardCharsets.UTF_8); - propertiesMap.put("content", properties); - } catch (final IOException e) { - propertiesMap.put("content", ""); - } - toscaPolicy.setProperties(propertiesMap); - final List<ToscaPolicy> toscaPolicies = new ArrayList<ToscaPolicy>(); - toscaPolicies.add(toscaPolicy); - pdpUpdateMsg.setPolicies(toscaPolicies); - pdpUpdateMessageListener.onTopicEvent(INFRA, TOPIC, null, pdpUpdateMsg); - return pdpUpdateMsg; - } - @Test public void testPdpStateChangeMessageListener_passivetopassive() { final PdpStatus pdpStatus = Registry.get(ApexStarterConstants.REG_PDP_STATUS_OBJECT); - performPdpUpdate(pdpStatus.getName()); - final PdpStateChange pdpStateChangeMsg = new PdpStateChange(); - pdpStateChangeMsg.setState(PdpState.PASSIVE); - pdpStateChangeMsg.setPdpGroup("pdpGroup"); - pdpStateChangeMsg.setPdpSubgroup("pdpSubgroup"); - pdpStateChangeMsg.setName(pdpStatus.getName()); + pdpUpdateMessageListener.onTopicEvent(INFRA, TOPIC, null, + TestListenerUtils.createPdpUpdateMsg(pdpStatus, new ArrayList<ToscaPolicy>())); + PdpStateChange pdpStateChangeMsg = + TestListenerUtils.createPdpStateChangeMsg(PdpState.PASSIVE, "pdpGroup", "pdpSubgroup", pdpStatus.getName()); pdpStateChangeListener.onTopicEvent(INFRA, TOPIC, null, pdpStateChangeMsg); assertEquals(pdpStatus.getState(), pdpStateChangeMsg.getState()); @@ -158,15 +131,57 @@ public class TestPdpStateChangeListener { @Test public void testPdpStateChangeMessageListener_activetoactive() { final PdpStatus pdpStatus = Registry.get(ApexStarterConstants.REG_PDP_STATUS_OBJECT); - performPdpUpdate(pdpStatus.getName()); + pdpUpdateMessageListener.onTopicEvent(INFRA, TOPIC, null, + TestListenerUtils.createPdpUpdateMsg(pdpStatus, new ArrayList<ToscaPolicy>())); pdpStatus.setState(PdpState.ACTIVE); - final PdpStateChange pdpStateChangeMsg = new PdpStateChange(); - pdpStateChangeMsg.setState(PdpState.ACTIVE); - pdpStateChangeMsg.setPdpGroup("pdpGroup"); - pdpStateChangeMsg.setPdpSubgroup("pdpSubgroup"); - pdpStateChangeMsg.setName(pdpStatus.getName()); + PdpStateChange pdpStateChangeMsg = + TestListenerUtils.createPdpStateChangeMsg(PdpState.ACTIVE, "pdpGroup", "pdpSubgroup", pdpStatus.getName()); pdpStateChangeListener.onTopicEvent(INFRA, TOPIC, null, pdpStateChangeMsg); assertEquals(pdpStatus.getState(), pdpStateChangeMsg.getState()); } + + @Test + public void testPdpStateChangeMessageListener() throws InterruptedException, CoderException { + OutputStream outContent = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outContent)); + final PdpStatus pdpStatus = Registry.get(ApexStarterConstants.REG_PDP_STATUS_OBJECT); + pdpUpdateMessageListener.onTopicEvent(INFRA, TOPIC, null, + TestListenerUtils.createPdpUpdateMsg(pdpStatus, new ArrayList<ToscaPolicy>())); + PdpStateChange pdpStateChangeMsg = + TestListenerUtils.createPdpStateChangeMsg(PdpState.ACTIVE, "pdpGroup", "pdpSubgroup", pdpStatus.getName()); + pdpStateChangeListener.onTopicEvent(INFRA, TOPIC, null, pdpStateChangeMsg); + assertTrue(outContent.toString().contains("State changed to active. No policies found.")); + + final ToscaPolicy toscaPolicy = + TestListenerUtils.createToscaPolicy("apex policy name", "1.0", "src/test/resources/dummyProperties.json"); + final List<ToscaPolicy> toscaPolicies = new ArrayList<ToscaPolicy>(); + toscaPolicies.add(toscaPolicy); + final PdpUpdate pdpUpdateMsg = TestListenerUtils.createPdpUpdateMsg(pdpStatus, toscaPolicies); + pdpUpdateMessageListener.onTopicEvent(INFRA, TOPIC, null, pdpUpdateMsg); + assertTrue(outContent.toString().contains("Apex engine started and policies are running.")); + assertEquals(PdpState.ACTIVE, pdpStatus.getState()); + } + + @Test + public void testPdpStateChangeMessageListener_activetopassive() throws InterruptedException, CoderException { + final PdpStatus pdpStatus = Registry.get(ApexStarterConstants.REG_PDP_STATUS_OBJECT); + final ToscaPolicy toscaPolicy = + TestListenerUtils.createToscaPolicy("apex policy name", "1.0", "src/test/resources/dummyProperties.json"); + final List<ToscaPolicy> toscaPolicies = new ArrayList<ToscaPolicy>(); + toscaPolicies.add(toscaPolicy); + final PdpUpdate pdpUpdateMsg = TestListenerUtils.createPdpUpdateMsg(pdpStatus, toscaPolicies); + pdpUpdateMessageListener.onTopicEvent(INFRA, TOPIC, null, pdpUpdateMsg); + PdpStateChange pdpStateChangeMsg = + TestListenerUtils.createPdpStateChangeMsg(PdpState.ACTIVE, "pdpGroup", "pdpSubgroup", pdpStatus.getName()); + pdpStateChangeListener.onTopicEvent(INFRA, TOPIC, null, pdpStateChangeMsg); + pdpStateChangeMsg = + TestListenerUtils.createPdpStateChangeMsg(PdpState.PASSIVE, "pdpGroup", "pdpSubgroup", pdpStatus.getName()); + OutputStream outContent = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outContent)); + pdpStateChangeListener.onTopicEvent(INFRA, TOPIC, null, pdpStateChangeMsg); + final String outString = outContent.toString(); + assertTrue(outString.contains("Apex pdp state changed from Active to Passive.")); + assertEquals(PdpState.PASSIVE, pdpStatus.getState()); + } } diff --git a/services/services-onappf/src/test/java/org/onap/policy/apex/services/onappf/comm/TestPdpUpdateListener.java b/services/services-onappf/src/test/java/org/onap/policy/apex/services/onappf/comm/TestPdpUpdateListener.java index 700797812..05656af96 100644 --- a/services/services-onappf/src/test/java/org/onap/policy/apex/services/onappf/comm/TestPdpUpdateListener.java +++ b/services/services-onappf/src/test/java/org/onap/policy/apex/services/onappf/comm/TestPdpUpdateListener.java @@ -2,7 +2,6 @@ * ============LICENSE_START======================================================= * Copyright (C) 2019 Nordix Foundation. * Modifications 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. @@ -23,16 +22,15 @@ package org.onap.policy.apex.services.onappf.comm; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import java.io.ByteArrayOutputStream; import java.io.FileNotFoundException; import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Paths; +import java.io.OutputStream; +import java.io.PrintStream; import java.util.ArrayList; -import java.util.LinkedHashMap; import java.util.List; -import java.util.Map; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -40,13 +38,17 @@ import org.onap.policy.apex.services.onappf.ApexStarterActivator; import org.onap.policy.apex.services.onappf.ApexStarterCommandLineArguments; import org.onap.policy.apex.services.onappf.ApexStarterConstants; import org.onap.policy.apex.services.onappf.exception.ApexStarterException; +import org.onap.policy.apex.services.onappf.handler.ApexEngineHandler; import org.onap.policy.apex.services.onappf.handler.PdpMessageHandler; import org.onap.policy.apex.services.onappf.parameters.ApexStarterParameterGroup; import org.onap.policy.apex.services.onappf.parameters.ApexStarterParameterHandler; import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; +import org.onap.policy.common.utils.coder.CoderException; import org.onap.policy.common.utils.services.Registry; +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.PdpState; import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; /** @@ -56,9 +58,12 @@ import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; */ public class TestPdpUpdateListener { private PdpUpdateListener pdpUpdateMessageListener; + private PdpStateChangeListener pdpStateChangeListener; private static final CommInfrastructure INFRA = CommInfrastructure.NOOP; private static final String TOPIC = "my-topic"; private ApexStarterActivator activator; + private ApexEngineHandler apexEngineHandler; + private PrintStream stdout = System.out; /** * Method for setup before each test. @@ -70,7 +75,7 @@ public class TestPdpUpdateListener { @Before public void setUp() throws ApexStarterException, FileNotFoundException, IOException { Registry.newRegistry(); - final String[] apexStarterConfigParameters = { "-c", "src/test/resources/ApexStarterConfigParameters.json" }; + final String[] apexStarterConfigParameters = {"-c", "src/test/resources/ApexStarterConfigParametersNoop.json"}; final ApexStarterCommandLineArguments arguments = new ApexStarterCommandLineArguments(); ApexStarterParameterGroup parameterGroup; // The arguments return a string if there is a message to print and we should @@ -89,6 +94,7 @@ public class TestPdpUpdateListener { Registry.register(ApexStarterConstants.REG_APEX_STARTER_ACTIVATOR, activator); activator.initialize(); pdpUpdateMessageListener = new PdpUpdateListener(); + pdpStateChangeListener = new PdpStateChangeListener(); } /** @@ -98,7 +104,12 @@ public class TestPdpUpdateListener { */ @After public void teardown() throws Exception { - + System.setOut(stdout); + apexEngineHandler = + Registry.getOrDefault(ApexStarterConstants.REG_APEX_ENGINE_HANDLER, ApexEngineHandler.class, null); + if (null != apexEngineHandler && apexEngineHandler.isApexEngineRunning()) { + apexEngineHandler.shutdown(); + } // clear the apex starter activator if (activator != null && activator.isAlive()) { activator.terminate(); @@ -106,35 +117,88 @@ public class TestPdpUpdateListener { } @Test - public void testPdpUpdateMssageListener() { + public void testPdpUpdateMssageListener() throws CoderException { final PdpStatus pdpStatus = Registry.get(ApexStarterConstants.REG_PDP_STATUS_OBJECT); - final PdpUpdate pdpUpdateMsg = new PdpUpdate(); - pdpUpdateMsg.setDescription("dummy pdp status for test"); - pdpUpdateMsg.setPdpGroup("pdpGroup"); - pdpUpdateMsg.setPdpSubgroup("pdpSubgroup"); - pdpUpdateMsg.setName(pdpStatus.getName()); - pdpUpdateMsg.setPdpHeartbeatIntervalMs(Long.valueOf(3000)); - final ToscaPolicy toscaPolicy = new ToscaPolicy(); - toscaPolicy.setType("apexpolicytype"); - toscaPolicy.setVersion("1.0"); - toscaPolicy.setName("apex policy name"); - final Map<String, Object> propertiesMap = new LinkedHashMap<>(); - String properties; - try { - properties = new String(Files.readAllBytes(Paths.get("src\\test\\resources\\dummyProperties.json")), - StandardCharsets.UTF_8); - propertiesMap.put("content", properties); - } catch (final IOException e) { - propertiesMap.put("content", ""); - } - toscaPolicy.setProperties(propertiesMap); + final ToscaPolicy toscaPolicy = + TestListenerUtils.createToscaPolicy("apex policy name", "1.0", "src/test/resources/dummyProperties.json"); + final List<ToscaPolicy> toscaPolicies = new ArrayList<ToscaPolicy>(); + toscaPolicies.add(toscaPolicy); + final PdpUpdate pdpUpdateMsg = TestListenerUtils.createPdpUpdateMsg(pdpStatus, toscaPolicies); + pdpUpdateMessageListener.onTopicEvent(INFRA, TOPIC, null, pdpUpdateMsg); + assertEquals(pdpStatus.getPdpGroup(), pdpUpdateMsg.getPdpGroup()); + assertEquals(pdpStatus.getPdpSubgroup(), pdpUpdateMsg.getPdpSubgroup()); + assertEquals(pdpStatus.getPolicies(), + new PdpMessageHandler().getToscaPolicyIdentifiers(pdpUpdateMsg.getPolicies())); + } + + @Test + public void testPdpUpdateMssageListener_success() throws InterruptedException, CoderException { + OutputStream outContent = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outContent)); + final PdpStatus pdpStatus = Registry.get(ApexStarterConstants.REG_PDP_STATUS_OBJECT); + pdpUpdateMessageListener.onTopicEvent(INFRA, TOPIC, null, + TestListenerUtils.createPdpUpdateMsg(pdpStatus, new ArrayList<ToscaPolicy>())); + PdpStateChange pdpStateChangeMsg = + TestListenerUtils.createPdpStateChangeMsg(PdpState.ACTIVE, "pdpGroup", "pdpSubgroup", pdpStatus.getName()); + pdpStateChangeListener.onTopicEvent(INFRA, TOPIC, null, pdpStateChangeMsg); + final ToscaPolicy toscaPolicy = + TestListenerUtils.createToscaPolicy("apex policy name", "1.0", "src/test/resources/dummyProperties.json"); final List<ToscaPolicy> toscaPolicies = new ArrayList<ToscaPolicy>(); toscaPolicies.add(toscaPolicy); - pdpUpdateMsg.setPolicies(toscaPolicies); + final PdpUpdate pdpUpdateMsg = TestListenerUtils.createPdpUpdateMsg(pdpStatus, toscaPolicies); pdpUpdateMessageListener.onTopicEvent(INFRA, TOPIC, null, pdpUpdateMsg); + final String outString = outContent.toString(); assertEquals(pdpStatus.getPdpGroup(), pdpUpdateMsg.getPdpGroup()); assertEquals(pdpStatus.getPdpSubgroup(), pdpUpdateMsg.getPdpSubgroup()); assertEquals(pdpStatus.getPolicies(), new PdpMessageHandler().getToscaPolicyIdentifiers(pdpUpdateMsg.getPolicies())); + assertTrue(outString.contains("Apex engine started and policies are running.")); + } + + @Test + public void testPdpUpdateMssageListener_undeploy() throws InterruptedException, CoderException { + final PdpStatus pdpStatus = Registry.get(ApexStarterConstants.REG_PDP_STATUS_OBJECT); + pdpUpdateMessageListener.onTopicEvent(INFRA, TOPIC, null, + TestListenerUtils.createPdpUpdateMsg(pdpStatus, new ArrayList<ToscaPolicy>())); + PdpStateChange pdpStateChangeMsg = + TestListenerUtils.createPdpStateChangeMsg(PdpState.ACTIVE, "pdpGroup", "pdpSubgroup", pdpStatus.getName()); + pdpStateChangeListener.onTopicEvent(INFRA, TOPIC, null, pdpStateChangeMsg); + final ToscaPolicy toscaPolicy = + TestListenerUtils.createToscaPolicy("apex policy name", "1.0", "src/test/resources/dummyProperties.json"); + final List<ToscaPolicy> toscaPolicies = new ArrayList<ToscaPolicy>(); + toscaPolicies.add(toscaPolicy); + final PdpUpdate pdpUpdateMsg = TestListenerUtils.createPdpUpdateMsg(pdpStatus, toscaPolicies); + pdpUpdateMessageListener.onTopicEvent(INFRA, TOPIC, null, pdpUpdateMsg); + OutputStream outContent = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outContent)); + pdpUpdateMessageListener.onTopicEvent(INFRA, TOPIC, null, + TestListenerUtils.createPdpUpdateMsg(pdpStatus, new ArrayList<ToscaPolicy>())); + final String outString = outContent.toString(); + assertTrue(outString.contains("Pdp update successful. No policies are running.")); + + } + + @Test + public void testPdpUpdateMssageListener_multi_policy_duplicate() + throws InterruptedException, ApexStarterException, CoderException { + OutputStream outContent = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outContent)); + final PdpStatus pdpStatus = Registry.get(ApexStarterConstants.REG_PDP_STATUS_OBJECT); + final ToscaPolicy toscaPolicy = + TestListenerUtils.createToscaPolicy("apex policy name", "1.0", "src/test/resources/dummyProperties.json"); + final ToscaPolicy toscaPolicy2 = + TestListenerUtils.createToscaPolicy("apexpolicy2", "1.0", "src/test/resources/dummyProperties.json"); + final List<ToscaPolicy> toscaPolicies = new ArrayList<ToscaPolicy>(); + toscaPolicies.add(toscaPolicy); + toscaPolicies.add(toscaPolicy2); + final PdpUpdate pdpUpdateMsg = TestListenerUtils.createPdpUpdateMsg(pdpStatus, toscaPolicies); + pdpUpdateMessageListener.onTopicEvent(INFRA, TOPIC, null, pdpUpdateMsg); + PdpStateChange pdpStateChangeMsg = + TestListenerUtils.createPdpStateChangeMsg(PdpState.ACTIVE, "pdpGroup", "pdpSubgroup", pdpStatus.getName()); + pdpStateChangeListener.onTopicEvent(INFRA, TOPIC, null, pdpStateChangeMsg); + final String outString = outContent.toString(); + assertTrue(outString.contains( + "Apex engine started. But, only the following polices are running - apex policy name:1.0 . " + + "Other policies failed execution. Please see the logs for more details.")); } } diff --git a/services/services-onappf/src/test/java/org/onap/policy/apex/services/onappf/parameters/dummyclasses/DummyStateFinalizerExecutor.java b/services/services-onappf/src/test/java/org/onap/policy/apex/services/onappf/parameters/dummyclasses/DummyStateFinalizerExecutor.java new file mode 100644 index 000000000..cdbd27b8f --- /dev/null +++ b/services/services-onappf/src/test/java/org/onap/policy/apex/services/onappf/parameters/dummyclasses/DummyStateFinalizerExecutor.java @@ -0,0 +1,42 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. All rights reserved. + * Modifications Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.services.onappf.parameters.dummyclasses; + +import java.util.Map; +import java.util.Properties; +import org.onap.policy.apex.context.ContextException; +import org.onap.policy.apex.core.engine.executor.StateFinalizerExecutor; +import org.onap.policy.apex.core.engine.executor.exception.StateMachineException; + +/** + * Dummy state finalizer executor for testing. + */ +public class DummyStateFinalizerExecutor extends StateFinalizerExecutor { + public DummyStateFinalizerExecutor() {} + + @Override + public String execute(final long executionId, final Properties executorProperties, + final Map<String, Object> newIncomingFields) throws StateMachineException, ContextException { + + return "stateOutput0"; + } +} diff --git a/services/services-onappf/src/test/java/org/onap/policy/apex/services/onappf/parameters/dummyclasses/DummyTaskExecutor.java b/services/services-onappf/src/test/java/org/onap/policy/apex/services/onappf/parameters/dummyclasses/DummyTaskExecutor.java new file mode 100644 index 000000000..d3fa9b570 --- /dev/null +++ b/services/services-onappf/src/test/java/org/onap/policy/apex/services/onappf/parameters/dummyclasses/DummyTaskExecutor.java @@ -0,0 +1,58 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. All rights reserved. + * Modifications Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.services.onappf.parameters.dummyclasses; + +import java.util.Map; +import java.util.Properties; +import org.onap.policy.apex.context.ContextException; +import org.onap.policy.apex.core.engine.event.EnEvent; +import org.onap.policy.apex.core.engine.executor.TaskExecutor; +import org.onap.policy.apex.core.engine.executor.exception.StateMachineException; +import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey; +import org.onap.policy.apex.model.policymodel.concepts.AxTask; + +/** + * Dummy task executor for testing. + */ +public class DummyTaskExecutor extends TaskExecutor { + public DummyTaskExecutor() {} + + @Override + public void prepare() throws StateMachineException {} + + @Override + public Map<String, Object> execute(final long executionId, final Properties executorProperties, + final Map<String, Object> newIncomingFields) throws StateMachineException, ContextException { + + AxArtifactKey event0Key = new AxArtifactKey("Event0:0.0.1"); + return new EnEvent(event0Key); + } + + @Override + public AxTask getSubject() { + AxArtifactKey taskKey = new AxArtifactKey("FirstTask:0.0.1"); + return new AxTask(taskKey); + } + + @Override + public void cleanUp() throws StateMachineException {} +} diff --git a/services/services-onappf/src/test/java/org/onap/policy/apex/services/onappf/parameters/dummyclasses/DummyTaskSelectExecutor.java b/services/services-onappf/src/test/java/org/onap/policy/apex/services/onappf/parameters/dummyclasses/DummyTaskSelectExecutor.java new file mode 100644 index 000000000..b27ff6ebc --- /dev/null +++ b/services/services-onappf/src/test/java/org/onap/policy/apex/services/onappf/parameters/dummyclasses/DummyTaskSelectExecutor.java @@ -0,0 +1,49 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. All rights reserved. + * Modifications Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.services.onappf.parameters.dummyclasses; + +import java.util.Properties; +import org.onap.policy.apex.context.ContextException; +import org.onap.policy.apex.core.engine.event.EnEvent; +import org.onap.policy.apex.core.engine.executor.TaskSelectExecutor; +import org.onap.policy.apex.core.engine.executor.exception.StateMachineException; +import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey; + +/** + * Dummy task selection executor for testing. + */ +public class DummyTaskSelectExecutor extends TaskSelectExecutor { + public DummyTaskSelectExecutor() {} + + @Override + public void prepare() throws StateMachineException {} + + @Override + public AxArtifactKey execute(final long executionId, final Properties executorProperties, + final EnEvent newIncomingEvent) throws StateMachineException, ContextException { + + return new AxArtifactKey("task:0.0.1"); + } + + @Override + public void cleanUp() throws StateMachineException {} +} diff --git a/services/services-onappf/src/test/java/org/onap/policy/apex/services/onappf/parameters/dummyclasses/SuperDooperExecutorParameters.java b/services/services-onappf/src/test/java/org/onap/policy/apex/services/onappf/parameters/dummyclasses/SuperDooperExecutorParameters.java new file mode 100644 index 000000000..cbcd23c73 --- /dev/null +++ b/services/services-onappf/src/test/java/org/onap/policy/apex/services/onappf/parameters/dummyclasses/SuperDooperExecutorParameters.java @@ -0,0 +1,39 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. All rights reserved. + * Modifications Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.services.onappf.parameters.dummyclasses; + +import org.onap.policy.apex.core.engine.ExecutorParameters; + +/** + * Dummy executor parameters. + */ +public class SuperDooperExecutorParameters extends ExecutorParameters { + + /** + * Instantiates a new super dooper executor parameters. + */ + public SuperDooperExecutorParameters() { + this.setTaskExecutorPluginClass(DummyTaskExecutor.class.getName()); + this.setTaskSelectionExecutorPluginClass(DummyTaskSelectExecutor.class.getName()); + this.setStateFinalizerExecutorPluginClass(DummyStateFinalizerExecutor.class.getName()); + } +} diff --git a/services/services-onappf/src/test/resources/ApexStarterConfigParametersNoop.json b/services/services-onappf/src/test/resources/ApexStarterConfigParametersNoop.json new file mode 100644 index 000000000..bce20da9d --- /dev/null +++ b/services/services-onappf/src/test/resources/ApexStarterConfigParametersNoop.json @@ -0,0 +1,28 @@ +{ + "name":"ApexStarterParameterGroup", + "restServerParameters": { + "host": "0.0.0.0", + "port": 6969, + "userName": "healthcheck", + "password": "zb!XztG34", + "https": true + }, + "pdpStatusParameters":{ + "timeIntervalMs": 120000, + "pdpType":"apex", + "description":"Pdp Heartbeat", + "supportedPolicyTypes":[{"name":"onap.policies.controlloop.operational.Apex","version":"1.0.0"}] + }, + "topicParameterGroup": { + "topicSources" : [ { + "topic" : "my-topic", + "servers" : [ "my-server" ], + "topicCommInfrastructure" : "noop" + }], + "topicSinks" : [ { + "topic" : "my-topic", + "servers" : [ "my-server" ], + "topicCommInfrastructure" : "noop" + }] + } +}
\ No newline at end of file diff --git a/services/services-onappf/src/test/resources/TestPojoEvent.json b/services/services-onappf/src/test/resources/TestPojoEvent.json new file mode 100644 index 000000000..ce2cb2b6b --- /dev/null +++ b/services/services-onappf/src/test/resources/TestPojoEvent.json @@ -0,0 +1,15 @@ +{ + "anInt": 1, + "anInteger": 2, + "someString": "a string", + "testSubPojo": { + "anInt": 10, + "anInteger": 20, + "someString": "a sub string", + "testSubSubPojo": { + "anInt": 100, + "anInteger": 200, + "someString": "a sub sub string" + } + } +} diff --git a/services/services-onappf/src/test/resources/dummyProperties.json b/services/services-onappf/src/test/resources/dummyProperties.json index 849b86e69..daf2d5049 100644 --- a/services/services-onappf/src/test/resources/dummyProperties.json +++ b/services/services-onappf/src/test/resources/dummyProperties.json @@ -1,43 +1,497 @@ { - "engineServiceParameters": { - "name": "MyApexEngine", - "version": "0.0.1", - "id": 45, - "instanceCount": 2, - "deploymentPort": 65522, - "policy_type_impl": "onap.policies.controlloop.operational.apex.sampledomain.Impl", - "engineParameters": { - "executorParameters": { - "JAVASCRIPT": { - "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" - } - } + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 2, + "deploymentPort": 65522, + "policy_type_impl": { + "apexPolicyModel": { + "key": { + "name": "SmallModel", + "version": "0.0.1" + }, + "keyInformation": { + "key": { + "name": "SmallModel_KeyInfo", + "version": "0.0.1" + }, + "keyInfoMap": { + "entry": [ + { + "key": { + "name": "BasicContextAlbum", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "BasicContextAlbum", + "version": "0.0.1" + }, + "UUID": "fec1b353-b35f-4384-b7d9-69622059c248", + "description": "Generated description for a concept called \"BasicContextAlbum\" with version \"0.0.1\" and UUID \"fec1b353-b35f-4384-b7d9-69622059c248\"" + } + }, + { + "key": { + "name": "BasicEvent", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "BasicEvent", + "version": "0.0.1" + }, + "UUID": "cc8d3c1a-e975-459a-bcd2-69f423eaa1f3", + "description": "Generated description for a concept called \"BasicEvent\" with version \"0.0.1\" and UUID \"cc8d3c1a-e975-459a-bcd2-69f423eaa1f3\"" + } + }, + { + "key": { + "name": "BasicPolicy", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "BasicPolicy", + "version": "0.0.1" + }, + "UUID": "d0c5d8ee-5fe7-4978-89ce-4a3e69cad043", + "description": "Generated description for a concept called \"BasicPolicy\" with version \"0.0.1\" and UUID \"d0c5d8ee-5fe7-4978-89ce-4a3e69cad043\"" + } + }, + { + "key": { + "name": "BasicTask", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "BasicTask", + "version": "0.0.1" + }, + "UUID": "c5651414-fc1c-493b-878d-75f0ce685c36", + "description": "Generated description for a concept called \"BasicTask\" with version \"0.0.1\" and UUID \"c5651414-fc1c-493b-878d-75f0ce685c36\"" + } + }, + { + "key": { + "name": "IntType", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "IntType", + "version": "0.0.1" + }, + "UUID": "790ff718-8dc0-44e0-89d8-1b3bbe238310", + "description": "Generated description for a concept called \"IntType\" with version \"0.0.1\" and UUID \"790ff718-8dc0-44e0-89d8-1b3bbe238310\"" + } + }, + { + "key": { + "name": "SmallModel", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "SmallModel", + "version": "0.0.1" + }, + "UUID": "a1bd1f4e-713b-456b-b1a8-bb48beee28e8", + "description": "Generated description for a concept called \"SmallModel\" with version \"0.0.1\" and UUID \"a1bd1f4e-713b-456b-b1a8-bb48beee28e8\"" + } + }, + { + "key": { + "name": "SmallModel_Albums", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "SmallModel_Albums", + "version": "0.0.1" + }, + "UUID": "72bed9af-ab7d-3379-b9f7-b5eca5c9ef22", + "description": "Generated description for concept referred to by key \"SmallModel_Albums:0.0.1\"" + } + }, + { + "key": { + "name": "SmallModel_Events", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "SmallModel_Events", + "version": "0.0.1" + }, + "UUID": "796dc6b0-627d-34ae-a5e2-1bc4b4b486b8", + "description": "Generated description for concept referred to by key \"SmallModel_Events:0.0.1\"" + } + }, + { + "key": { + "name": "SmallModel_KeyInfo", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "SmallModel_KeyInfo", + "version": "0.0.1" + }, + "UUID": "b4876774-6907-3d27-a2b8-f05737c5ee4a", + "description": "Generated description for concept referred to by key \"SmallModel_KeyInfo:0.0.1\"" + } + }, + { + "key": { + "name": "SmallModel_Policies", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "SmallModel_Policies", + "version": "0.0.1" + }, + "UUID": "5bcf946b-67be-3190-a906-f954896f999f", + "description": "Generated description for concept referred to by key \"SmallModel_Policies:0.0.1\"" + } + }, + { + "key": { + "name": "SmallModel_Schemas", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "SmallModel_Schemas", + "version": "0.0.1" + }, + "UUID": "c25bf5c3-7f1e-3667-b8a9-971ba21517bc", + "description": "Generated description for concept referred to by key \"SmallModel_Schemas:0.0.1\"" + } + }, + { + "key": { + "name": "SmallModel_Tasks", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "SmallModel_Tasks", + "version": "0.0.1" + }, + "UUID": "43b015ca-2ed1-3a35-b103-e8a5aa68f1ef", + "description": "Generated description for concept referred to by key \"SmallModel_Tasks:0.0.1\"" + } + } + ] + } + }, + "policies": { + "key": { + "name": "SmallModel_Policies", + "version": "0.0.1" + }, + "policyMap": { + "entry": [ + { + "key": { + "name": "BasicPolicy", + "version": "0.0.1" + }, + "value": { + "policyKey": { + "name": "BasicPolicy", + "version": "0.0.1" + }, + "template": "FREEFORM", + "state": { + "entry": [ + { + "key": "OnlyState", + "value": { + "stateKey": { + "parentKeyName": "BasicPolicy", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "OnlyState" + }, + "trigger": { + "name": "BasicEvent", + "version": "0.0.1" + }, + "stateOutputs": { + "entry": [ + { + "key": "OnlyOutput", + "value": { + "key": { + "parentKeyName": "BasicPolicy", + "parentKeyVersion": "0.0.1", + "parentLocalName": "OnlyState", + "localName": "OnlyOutput" + }, + "outgoingEvent": { + "name": "BasicEvent", + "version": "0.0.1" + }, + "nextState": { + "parentKeyName": "NULL", + "parentKeyVersion": "0.0.0", + "parentLocalName": "NULL", + "localName": "NULL" + } + } + } + ] + }, + "contextAlbumReference": [ + { + "name": "BasicContextAlbum", + "version": "0.0.1" + } + ], + "taskSelectionLogic": { + "key": "NULL", + "logicFlavour": "UNDEFINED", + "logic": "" + }, + "stateFinalizerLogicMap": { + "entry": [] + }, + "defaultTask": { + "name": "BasicTask", + "version": "0.0.1" + }, + "taskReferences": { + "entry": [ + { + "key": { + "name": "BasicTask", + "version": "0.0.1" + }, + "value": { + "key": { + "parentKeyName": "BasicPolicy", + "parentKeyVersion": "0.0.1", + "parentLocalName": "OnlyState", + "localName": "BasicTask" + }, + "outputType": "DIRECT", + "output": { + "parentKeyName": "BasicPolicy", + "parentKeyVersion": "0.0.1", + "parentLocalName": "OnlyState", + "localName": "OnlyOutput" + } + } + } + ] + } + } + } + ] + }, + "firstState": "OnlyState" + } + } + ] + } + }, + "tasks": { + "key": { + "name": "SmallModel_Tasks", + "version": "0.0.1" + }, + "taskMap": { + "entry": [ + { + "key": { + "name": "BasicTask", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "BasicTask", + "version": "0.0.1" + }, + "inputFields": { + "entry": [ + { + "key": "intPar", + "value": { + "key": "intPar", + "fieldSchemaKey": { + "name": "IntType", + "version": "0.0.1" + }, + "optional": false + } + } + ] + }, + "outputFields": { + "entry": [ + { + "key": "intPar", + "value": { + "key": "intPar", + "fieldSchemaKey": { + "name": "IntType", + "version": "0.0.1" + }, + "optional": false + } + } + ] + }, + "taskParameters": { + "entry": [] + }, + "contextAlbumReference": [ + { + "name": "BasicContextAlbum", + "version": "0.0.1" + } + ], + "taskLogic": { + "key": "TaskLogic", + "logicFlavour": "JAVASCRIPT", + "logic": "executor.logger.debug(executor.subject.id);\nvar gc = executor.getContextAlbum(\"BasicContextAlbum\");\nexecutor.logger.debug(gc.name);\nexecutor.logger.debug(executor.inFields);\n\nexecutor.logger.debug(executor.eo);\n\nvar returnValue = executor.isTrue;" + } + } + } + ] + } + }, + "events": { + "key": { + "name": "SmallModel_Events", + "version": "0.0.1" + }, + "eventMap": { + "entry": [ + { + "key": { + "name": "BasicEvent", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "BasicEvent", + "version": "0.0.1" + }, + "nameSpace": "org.onap.policy.apex.events", + "source": "source", + "target": "target", + "parameter": { + "entry": [ + { + "key": "intPar", + "value": { + "key": "intPar", + "fieldSchemaKey": { + "name": "IntType", + "version": "0.0.1" + }, + "optional": false + } + } + ] + } + } + } + ] + } + }, + "albums": { + "key": { + "name": "SmallModel_Albums", + "version": "0.0.1" + }, + "albums": { + "entry": [ + { + "key": { + "name": "BasicContextAlbum", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "BasicContextAlbum", + "version": "0.0.1" + }, + "scope": "GLOBAL", + "isWritable": true, + "itemSchema": { + "name": "IntType", + "version": "0.0.1" + } + } + } + ] + } + }, + "schemas": { + "key": { + "name": "SmallModel_Schemas", + "version": "0.0.1" + }, + "schemas": { + "entry": [ + { + "key": { + "name": "IntType", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "IntType", + "version": "0.0.1" + }, + "schemaFlavour": "Java", + "schemaDefinition": "java.lang.Integer" + } + } + ] + } } + } }, - "eventOutputParameters": { - "FirstProducer": { - "carrierTechnologyParameters": { - "carrierTechnology": "FILE", - "parameters": { - "standardIo": true - } - }, - "eventProtocolParameters": { - "eventProtocol": "JSON" - } + "engineParameters": { + "executorParameters": { + "JAVASCRIPT": { + "parameterClassName": "org.onap.policy.apex.services.onappf.parameters.dummyclasses.SuperDooperExecutorParameters" } - }, - "eventInputParameters": { - "TheFileConsumer1": { - "carrierTechnologyParameters": { - "carrierTechnology": "FILE", - "parameters": { - "fileName": "src/test/resources/events/TestPojoEvent.json" - } - }, - "eventProtocolParameters": { - "eventProtocol": "JSON" - } + } + } + }, + "eventOutputParameters": { + "FirstProducer": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "standardIo": true + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + } + } + }, + "eventInputParameters": { + "TheFileConsumer1": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "src/test/resources/TestPojoEvent.json" } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + } } + } }
\ No newline at end of file diff --git a/testsuites/integration/integration-uservice-test/src/test/java/org/onap/policy/apex/testsuites/integration/uservice/adapt/restclient/TestExecutionPropertyRest.java b/testsuites/integration/integration-uservice-test/src/test/java/org/onap/policy/apex/testsuites/integration/uservice/adapt/restclient/TestExecutionPropertyRest.java index b61c70961..f3ce83c5a 100644 --- a/testsuites/integration/integration-uservice-test/src/test/java/org/onap/policy/apex/testsuites/integration/uservice/adapt/restclient/TestExecutionPropertyRest.java +++ b/testsuites/integration/integration-uservice-test/src/test/java/org/onap/policy/apex/testsuites/integration/uservice/adapt/restclient/TestExecutionPropertyRest.java @@ -20,6 +20,13 @@ package org.onap.policy.apex.testsuites.integration.uservice.adapt.restclient; +import static org.junit.Assert.assertTrue; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.core.Response; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; @@ -34,14 +41,6 @@ import org.onap.policy.common.utils.network.NetworkUtil; import org.slf4j.ext.XLogger; import org.slf4j.ext.XLoggerFactory; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.core.Response; -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; - -import static org.junit.Assert.assertTrue; - /** * This class runs integration tests for execution property in restClient. */ @@ -97,7 +96,7 @@ public class TestExecutionPropertyRest { server.start(); - if (!NetworkUtil.isTcpPortOpen("localHost", PORT, 2000, 1L)) { + if (!NetworkUtil.isTcpPortOpen("localHost", PORT, 60, 500L)) { throw new IllegalStateException("port " + PORT + " is still not in use"); } diff --git a/testsuites/integration/integration-uservice-test/src/test/java/org/onap/policy/apex/testsuites/integration/uservice/adapt/restclient/TestFile2Rest.java b/testsuites/integration/integration-uservice-test/src/test/java/org/onap/policy/apex/testsuites/integration/uservice/adapt/restclient/TestFile2Rest.java index 534d4bcf6..6393f3f04 100644 --- a/testsuites/integration/integration-uservice-test/src/test/java/org/onap/policy/apex/testsuites/integration/uservice/adapt/restclient/TestFile2Rest.java +++ b/testsuites/integration/integration-uservice-test/src/test/java/org/onap/policy/apex/testsuites/integration/uservice/adapt/restclient/TestFile2Rest.java @@ -6,22 +6,32 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * * SPDX-License-Identifier: Apache-2.0 * ============LICENSE_END========================================================= */ package org.onap.policy.apex.testsuites.integration.uservice.adapt.restclient; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + import com.google.gson.Gson; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.util.Map; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.core.Response; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; @@ -37,17 +47,6 @@ import org.onap.policy.common.utils.network.NetworkUtil; import org.slf4j.ext.XLogger; import org.slf4j.ext.XLoggerFactory; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.core.Response; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.PrintStream; -import java.util.Map; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - /** * The Class TestFile2Rest. */ @@ -79,7 +78,7 @@ public class TestFile2Rest { server.start(); - if (!NetworkUtil.isTcpPortOpen("localHost", PORT, 2000, 1L)) { + if (!NetworkUtil.isTcpPortOpen("localHost", PORT, 60, 500L)) { throw new IllegalStateException("port " + PORT + " is still not in use"); } } diff --git a/testsuites/integration/integration-uservice-test/src/test/java/org/onap/policy/apex/testsuites/integration/uservice/adapt/restclient/TestRest2File.java b/testsuites/integration/integration-uservice-test/src/test/java/org/onap/policy/apex/testsuites/integration/uservice/adapt/restclient/TestRest2File.java index c44950b9e..5dd2f0546 100644 --- a/testsuites/integration/integration-uservice-test/src/test/java/org/onap/policy/apex/testsuites/integration/uservice/adapt/restclient/TestRest2File.java +++ b/testsuites/integration/integration-uservice-test/src/test/java/org/onap/policy/apex/testsuites/integration/uservice/adapt/restclient/TestRest2File.java @@ -6,21 +6,27 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * * SPDX-License-Identifier: Apache-2.0 * ============LICENSE_END========================================================= */ package org.onap.policy.apex.testsuites.integration.uservice.adapt.restclient; +import static org.junit.Assert.fail; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.PrintStream; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; @@ -37,13 +43,6 @@ import org.onap.policy.common.utils.network.NetworkUtil; import org.slf4j.ext.XLogger; import org.slf4j.ext.XLoggerFactory; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.PrintStream; - -import static org.junit.Assert.fail; - /** * The Class TestRest2File. */ @@ -83,7 +82,7 @@ public class TestRest2File { server.start(); - if (!NetworkUtil.isTcpPortOpen("localHost", PORT, 2000, 1L)) { + if (!NetworkUtil.isTcpPortOpen("localHost", PORT, 60, 500L)) { throw new IllegalStateException("port " + PORT + " is still not in use"); } } @@ -268,7 +267,7 @@ public class TestRest2File { /** * Check if a required string exists in the output. - * + * * @param outputEventText the text to examine * @param requiredString the string to search for */ |