summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleFeature.java5
-rw-r--r--feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleFsm.java23
-rw-r--r--feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/PolicyTypeDroolsController.java1
-rw-r--r--feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/PolicyTypeNativeDroolsController.java17
-rw-r--r--feature-lifecycle/src/main/java/org/onap/policy/drools/server/restful/RestLifecycleManager.java194
-rw-r--r--feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/ControllerSupport.java18
-rw-r--r--feature-lifecycle/src/test/java/org/onap/policy/drools/server/restful/RestLifecycleManagerTest.java359
-rw-r--r--feature-lifecycle/src/test/resources/lifecycle.kmodule5
-rw-r--r--policy-management/src/main/java/org/onap/policy/drools/features/PolicyControllerFeatureApi.java7
-rw-r--r--policy-management/src/main/java/org/onap/policy/drools/system/internal/AggregatedPolicyController.java4
10 files changed, 534 insertions, 99 deletions
diff --git a/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleFeature.java b/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleFeature.java
index d9205977..12828e02 100644
--- a/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleFeature.java
+++ b/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleFeature.java
@@ -23,6 +23,7 @@ package org.onap.policy.drools.lifecycle;
import org.onap.policy.drools.features.DroolsControllerFeatureApi;
import org.onap.policy.drools.features.PolicyControllerFeatureApi;
import org.onap.policy.drools.features.PolicyEngineFeatureApi;
+import org.onap.policy.drools.protocol.configuration.DroolsConfiguration;
import org.onap.policy.drools.system.PolicyController;
import org.onap.policy.drools.system.PolicyEngine;
@@ -52,7 +53,9 @@ public class LifecycleFeature
}
@Override
- public boolean afterPatch(PolicyController controller, boolean success) {
+ public boolean afterPatch(
+ PolicyController controller, DroolsConfiguration oldConfiguration,
+ DroolsConfiguration newConfiguration, boolean success) {
return fsmPatch(controller);
}
diff --git a/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleFsm.java b/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleFsm.java
index 3ecb4b3a..ac76883f 100644
--- a/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleFsm.java
+++ b/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleFsm.java
@@ -31,6 +31,7 @@ import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;
@@ -189,6 +190,7 @@ public class LifecycleFsm implements Startable {
PolicyTypeDroolsController ptDroolsController = (PolicyTypeDroolsController) policyTypesMap.get(id);
if (ptDroolsController == null) {
policyTypesMap.put(id, new PolicyTypeDroolsController(this, id, controller));
+ logger.info("policy-type {} added", id);
} else {
ptDroolsController.add(controller);
}
@@ -219,14 +221,19 @@ public class LifecycleFsm implements Startable {
*/
public synchronized void stop(@NonNull PolicyController controller) {
logger.info("lifecycle event: stop controller: {}", controller.getName());
- for (ToscaPolicyTypeIdentifier id : controller.getPolicyTypes()) {
- if (!policyTypesMap.containsKey(id)) {
- continue;
- }
- PolicyTypeDroolsController ptDroolsController = (PolicyTypeDroolsController) policyTypesMap.get(id);
- ptDroolsController.remove(controller);
- if (ptDroolsController.controllers().isEmpty()) {
- policyTypesMap.remove(id);
+
+ List<PolicyTypeDroolsController> opControllers =
+ policyTypesMap.values().stream()
+ .filter(typeController -> typeController instanceof PolicyTypeDroolsController)
+ .map(typeController -> (PolicyTypeDroolsController) typeController)
+ .filter(opController -> opController.getControllers().containsKey(controller.getName()))
+ .collect(Collectors.toList());
+
+ for (PolicyTypeDroolsController opController : opControllers) {
+ opController.remove(controller);
+ if (opController.controllers().isEmpty()) {
+ policyTypesMap.remove(opController.getPolicyType());
+ logger.info("policy-type {} removed", opController.getPolicyType());
}
}
}
diff --git a/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/PolicyTypeDroolsController.java b/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/PolicyTypeDroolsController.java
index 2772d854..8dfbf2f3 100644
--- a/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/PolicyTypeDroolsController.java
+++ b/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/PolicyTypeDroolsController.java
@@ -52,6 +52,7 @@ public class PolicyTypeDroolsController implements PolicyTypeController {
private static final Logger logger = LoggerFactory.getLogger(PolicyTypeController.class);
+ @Getter
protected final Map<String, PolicyController> controllers = new ConcurrentHashMap<>();
@Getter
diff --git a/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/PolicyTypeNativeDroolsController.java b/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/PolicyTypeNativeDroolsController.java
index 8255c027..e74b2895 100644
--- a/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/PolicyTypeNativeDroolsController.java
+++ b/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/PolicyTypeNativeDroolsController.java
@@ -84,14 +84,23 @@ public class PolicyTypeNativeDroolsController implements PolicyTypeController {
PolicyController controller;
try {
- controller = PolicyEngineConstants.getManager()
- .createPolicyController(controllerConfig.getControllerName(), controllerProps);
+ controller =
+ PolicyEngineConstants.getManager()
+ .createPolicyController(controllerConfig.getControllerName(), controllerProps);
} catch (RuntimeException e) {
- logger.warn("failed deploy (cannot create controller) for policy: {}", policy);
+ logger.warn("failed deploy (cannot create controller) for policy: {}", policy, e);
return false;
}
- return controller != null;
+ try {
+ controller.start();
+ } catch (RuntimeException e) {
+ logger.warn("failed deploy (cannot start ontroller) for policy: {}", policy, e);
+ PolicyEngineConstants.getManager().removePolicyController(controller);
+ return false;
+ }
+
+ return true;
}
@Override
diff --git a/feature-lifecycle/src/main/java/org/onap/policy/drools/server/restful/RestLifecycleManager.java b/feature-lifecycle/src/main/java/org/onap/policy/drools/server/restful/RestLifecycleManager.java
index 3e55a10c..5c8f9dc2 100644
--- a/feature-lifecycle/src/main/java/org/onap/policy/drools/server/restful/RestLifecycleManager.java
+++ b/feature-lifecycle/src/main/java/org/onap/policy/drools/server/restful/RestLifecycleManager.java
@@ -21,9 +21,13 @@ package org.onap.policy.drools.server.restful;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
+import java.util.List;
import java.util.Properties;
+import java.util.stream.Collectors;
import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
+import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
@@ -33,12 +37,18 @@ import javax.ws.rs.core.Response;
import org.onap.policy.common.endpoints.event.comm.TopicSink;
import org.onap.policy.common.endpoints.event.comm.TopicSource;
import org.onap.policy.common.endpoints.http.server.YamlMessageBodyHandler;
+import org.onap.policy.common.utils.coder.CoderException;
+import org.onap.policy.common.utils.coder.StandardCoder;
import org.onap.policy.drools.lifecycle.LifecycleFeature;
import org.onap.policy.drools.lifecycle.PolicyTypeController;
import org.onap.policy.models.pdp.concepts.PdpStateChange;
+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;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifier;
import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* REST Lifecycle Manager.
@@ -50,6 +60,10 @@ import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifi
@Api
public class RestLifecycleManager {
+ private static final Logger logger = LoggerFactory.getLogger(RestLifecycleManager.class);
+
+ private static final StandardCoder coder = new StandardCoder();
+
/**
* GET group.
*/
@@ -213,16 +227,23 @@ public class RestLifecycleManager {
*/
@GET
- @Path("policyTypes/{policyType}/{policyVersion}")
+ @Path("policyTypes/{policyType}/{policyTypeVersion}")
@ApiOperation(value = "Entities associated with a policy type",
notes = "Lifecycle policy Types", response = PolicyTypeController.class)
public Response policyType(
- @ApiParam(value = "Policy Type", required = true) @PathParam("policyType") String policyType,
- @ApiParam(value = "Policy Type Version", required = true) @PathParam("policyVersion") String policyVersion) {
+ @ApiParam(value = "Policy Type", required = true)
+ @PathParam("policyType") String policyType,
+ @ApiParam(value = "Policy Type Version", required = true)
+ @PathParam("policyTypeVersion") String policyTypeVersion) {
+ PolicyTypeController typeController =
+ LifecycleFeature.fsm.getPolicyTypesMap()
+ .get(new ToscaPolicyTypeIdentifier(policyType, policyTypeVersion));
+ if (typeController == null) {
+ return Response.status(Response.Status.NOT_FOUND).build();
+ }
+
return Response.status(Response.Status.OK)
- .entity(LifecycleFeature.fsm
- .getPolicyTypesMap()
- .get(new ToscaPolicyTypeIdentifier(policyType, policyVersion)))
+ .entity(typeController)
.build();
}
@@ -232,8 +253,7 @@ public class RestLifecycleManager {
@GET
@Path("policies")
- @ApiOperation(value = "List of tracked policies",
- notes = "Lifecycle Policies", responseContainer = "List")
+ @ApiOperation(value = "List of policies", responseContainer = "List")
public Response policies() {
return Response.status(Response.Status.OK)
.entity(LifecycleFeature.fsm.getPoliciesMap().keySet())
@@ -242,28 +262,160 @@ public class RestLifecycleManager {
}
/**
+ * POST a Policy.
+ */
+
+ @POST
+ @Path("policies")
+ @ApiOperation(value = "Deploy a policy", response = Boolean.class)
+ public Response deployTrackedPolicy(
+ @ApiParam(value = "Tosca Policy", required = true) String policy) {
+
+ ToscaPolicy toscaPolicy = getToscaPolicy(policy);
+ if (toscaPolicy == null) {
+ return Response.status(Response.Status.NOT_ACCEPTABLE).build();
+ }
+
+ PolicyTypeController typeController = getPolicyTypeController(toscaPolicy);
+ if (typeController == null) {
+ return Response.status(Response.Status.NOT_FOUND).build();
+ }
+
+ List<ToscaPolicy> policies =
+ LifecycleFeature.fsm.getPoliciesMap().values().stream().collect(Collectors.toList());
+ policies.add(toscaPolicy);
+ return Response.status(Response.Status.OK)
+ .entity(LifecycleFeature.fsm.update(getPolicyUpdate(policies)))
+ .build();
+ }
+
+ /**
* GET a policy.
*/
@GET
- @Path("policies/{policy}/{policyVersion}")
- @ApiOperation(value = "Lifecycle tracked policy",
- notes = "Lifecycle Tracked Policy", response = ToscaPolicy.class)
+ @Path("policies/{policyName}/{policyVersion}")
+ @ApiOperation(value = "Retrieves a policy", response = ToscaPolicy.class)
public Response policy(
+ @ApiParam(value = "Policy Name", required = true) @PathParam("policyName") String policyName,
+ @ApiParam(value = "Policy Version", required = true) @PathParam("policyVersion") String policyVersion) {
+
+ ToscaPolicy policy;
+ try {
+ policy =
+ LifecycleFeature.fsm.getPoliciesMap().get(new ToscaPolicyIdentifier(policyName, policyVersion));
+ } catch (RuntimeException r) {
+ logger.debug("policy {}:{} has not been found", policyName, policyVersion, r);
+ return Response.status(Response.Status.NOT_FOUND).build();
+ }
+
+ if (policy == null) {
+ return Response.status(Response.Status.NOT_FOUND).build();
+ }
+
+ return Response.status(Response.Status.OK).entity(policy).build();
+ }
+
+ /**
+ * DELETE a policy.
+ */
+
+ @DELETE
+ @Path("policies/{policyName}/{policyVersion}")
+ @ApiOperation(value = "Deletes a Lifecycle tracked policy", response = Boolean.class)
+ public Response undeployPolicy(
@ApiParam(value = "Policy", required = true) @PathParam("policyName") String policyName,
@ApiParam(value = "Policy Version", required = true) @PathParam("policyVersion") String policyVersion) {
- ToscaPolicy policy = LifecycleFeature.fsm
- .getPoliciesMap()
- .get(new ToscaPolicyTypeIdentifier(policyName, policyVersion));
- if (policy != null) {
- return
- Response.status(Response.Status.OK)
- .entity(LifecycleFeature.fsm.getPolicyTypesMap()
- .get(new ToscaPolicyTypeIdentifier(policyName, policyVersion)))
- .build();
+ ToscaPolicy policy;
+ try {
+ policy =
+ LifecycleFeature.fsm.getPoliciesMap().get(new ToscaPolicyIdentifier(policyName, policyVersion));
+ } catch (RuntimeException r) {
+ logger.debug("policy {}:{} has not been found", policyName, policyVersion, r);
+ return Response.status(Response.Status.NOT_FOUND).build();
+ }
+
+ if (policy == null) {
+ return Response.status(Response.Status.NOT_FOUND).build();
+ }
+
+ List<ToscaPolicy> policies =
+ LifecycleFeature.fsm.getPoliciesMap().values().stream().collect(Collectors.toList());
+ policies.removeIf(aPolicy -> policy.getIdentifier().equals(aPolicy.getIdentifier()));
+ return Response.status(Response.Status.OK)
+ .entity(LifecycleFeature.fsm.update(getPolicyUpdate(policies)))
+ .build();
+ }
+
+ /**
+ * List of policies individual Operations supported.
+ */
+
+ @GET
+ @Path("policies/operations")
+ @ApiOperation(value = "Gets Policy Operations", responseContainer = "List")
+ public Response policiesOperations() {
+ return Response.status(Response.Status.OK).entity(List.of("deployment", "undeployment")).build();
+ }
+
+ /**
+ * POST a deployment operation on a policy.
+ */
+
+ @POST
+ @Path("policies/operations/deployment")
+ @ApiOperation(value = "Deploys a policy", notes = "Deploys a policy", response = Boolean.class)
+ public Response deployOperation(@ApiParam(value = "Tosca Policy", required = true) String policy) {
+ return deployUndeployOperation(policy, true);
+ }
+
+ /**
+ * POST an undeployment operation on a policy.
+ */
+
+ @POST
+ @Path("policies/operations/undeployment")
+ @ApiOperation(value = "Undeploys a policy", response = Boolean.class)
+ public Response undeployOperation(@ApiParam(value = "Tosca Policy", required = true) String policy) {
+ return deployUndeployOperation(policy, false);
+ }
+
+ private Response deployUndeployOperation(String policy, boolean deploy) {
+ ToscaPolicy toscaPolicy = getToscaPolicy(policy);
+ if (toscaPolicy == null) {
+ return Response.status(Response.Status.NOT_ACCEPTABLE).build();
+ }
+
+ PolicyTypeController typeController = getPolicyTypeController(toscaPolicy);
+ if (typeController == null) {
+ return Response.status(Response.Status.NOT_FOUND).build();
+ }
+
+ return Response.status(Response.Status.OK)
+ .entity((deploy) ? typeController.deploy(toscaPolicy) : typeController.undeploy(toscaPolicy))
+ .build();
+ }
+
+ private ToscaPolicy getToscaPolicy(String policy) {
+ try {
+ return coder.decode(policy, ToscaPolicy.class);
+ } catch (CoderException | RuntimeException e) {
+ return null;
}
+ }
+
+ private PolicyTypeController getPolicyTypeController(ToscaPolicy policy) {
+ return LifecycleFeature.fsm.getPolicyTypesMap().get(policy.getTypeIdentifier());
+ }
- return Response.status(Response.Status.NOT_FOUND).build();
+ private PdpUpdate getPolicyUpdate(List<ToscaPolicy> policies) {
+ PdpUpdate update = new PdpUpdate();
+ update.setName(LifecycleFeature.fsm.getName());
+ update.setPdpGroup(LifecycleFeature.fsm.getGroup());
+ update.setPdpSubgroup(LifecycleFeature.fsm.getSubgroup());
+ update.setPolicies(policies);
+ return update;
}
+
}
diff --git a/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/ControllerSupport.java b/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/ControllerSupport.java
index 9b673dd5..1e9f1c66 100644
--- a/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/ControllerSupport.java
+++ b/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/ControllerSupport.java
@@ -69,12 +69,7 @@ public class ControllerSupport {
;
}
- ReleaseId coordinates =
- KieUtils.installArtifact(Paths.get(JUNIT_KMODULE_PATH).toFile(),
- Paths.get(JUNIT_KMODULE_POM_PATH).toFile(),
- JUNIT_KJAR_DRL_PATH,
- Paths.get(JUNIT_KMODULE_DRL_PATH).toFile());
-
+ ReleaseId coordinates = installArtifact();
Properties controllerProps = new Properties();
controllerProps.put(DroolsPropertyConstants.PROPERTY_CONTROLLER_NAME, name);
@@ -87,6 +82,17 @@ public class ControllerSupport {
}
/**
+ * install artifact.
+ */
+ public ReleaseId installArtifact() throws IOException {
+ return
+ KieUtils.installArtifact(Paths.get(JUNIT_KMODULE_PATH).toFile(),
+ Paths.get(JUNIT_KMODULE_POM_PATH).toFile(),
+ JUNIT_KJAR_DRL_PATH,
+ Paths.get(JUNIT_KMODULE_DRL_PATH).toFile());
+ }
+
+ /**
* Destroy the echo controller.
*/
public void destroyController() {
diff --git a/feature-lifecycle/src/test/java/org/onap/policy/drools/server/restful/RestLifecycleManagerTest.java b/feature-lifecycle/src/test/java/org/onap/policy/drools/server/restful/RestLifecycleManagerTest.java
index 511fcc9b..2222399b 100644
--- a/feature-lifecycle/src/test/java/org/onap/policy/drools/server/restful/RestLifecycleManagerTest.java
+++ b/feature-lifecycle/src/test/java/org/onap/policy/drools/server/restful/RestLifecycleManagerTest.java
@@ -18,43 +18,87 @@
package org.onap.policy.drools.server.restful;
+import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.nio.file.Files;
+import java.nio.file.Paths;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
+import org.apache.commons.lang3.StringUtils;
import org.junit.After;
-import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
+import org.onap.policy.common.endpoints.event.comm.TopicEndpointManager;
+import org.onap.policy.common.endpoints.event.comm.bus.NoopTopicFactories;
import org.onap.policy.common.endpoints.event.comm.bus.internal.BusTopicParams;
import org.onap.policy.common.endpoints.http.client.HttpClient;
import org.onap.policy.common.endpoints.http.client.HttpClientFactoryInstance;
import org.onap.policy.common.endpoints.http.server.HttpServletServer;
import org.onap.policy.common.endpoints.http.server.HttpServletServerFactoryInstance;
+import org.onap.policy.common.endpoints.properties.PolicyEndPointProperties;
+import org.onap.policy.common.utils.coder.CoderException;
+import org.onap.policy.common.utils.coder.StandardCoder;
import org.onap.policy.common.utils.network.NetworkUtil;
+import org.onap.policy.common.utils.resources.ResourceUtils;
+import org.onap.policy.drools.lifecycle.ControllerSupport;
import org.onap.policy.drools.lifecycle.LifecycleFeature;
+import org.onap.policy.drools.lifecycle.LifecycleFsm;
import org.onap.policy.drools.persistence.SystemPersistenceConstants;
+import org.onap.policy.drools.system.PolicyControllerConstants;
+import org.onap.policy.drools.utils.logging.LoggerUtil;
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.ToscaServiceTemplate;
/**
* REST Lifecycle Manager Test.
*/
public class RestLifecycleManagerTest {
+ // Native Drools Policy
+ private static final String EXAMPLE_NATIVE_CONTROLLER_POLICY_NAME = "example.controller";
+ private static final String EXAMPLE_NATIVE_CONTROLLER_POLICY_JSON =
+ "src/test/resources/tosca-policy-native-controller-example.json";
+
+ private static final String EXAMPLE_NATIVE_ARTIFACT_POLICY_NAME = "example.artifact";
+ private static final String EXAMPLE_NATIVE_ARTIFACT_POLICY_JSON =
+ "src/test/resources/tosca-policy-native-artifact-example.json";
+
+ private static final String OP_POLICY_NAME_VCPE = "operational.restart";
+ private static final String VCPE_OPERATIONAL_DROOLS_POLICY_JSON =
+ "policies/vCPE.policy.operational.input.tosca.json";
+
+ private static StandardCoder coder = new StandardCoder();
+ private static ControllerSupport controllerSupport = new ControllerSupport("lifecycle");
+
+ private LifecycleFsm fsm;
+ private HttpClient client;
+
/**
* Set up.
*/
@Before
public void setUp() throws Exception {
+ SystemPersistenceConstants.getManager().setConfigurationDir("target/test-classes");
+ fsm = newFsmInstance();
+
+ LoggerUtil.setLevel(LoggerUtil.ROOT_LOGGER, "INFO");
+ LoggerUtil.setLevel("org.onap.policy.common.endpoints", "WARN");
+ LoggerUtil.setLevel("org.onap.policy.drools", "INFO");
+
HttpServletServerFactoryInstance.getServerFactory().destroy();
HttpClientFactoryInstance.getClientFactory().destroy();
-
- SystemPersistenceConstants.getManager().setConfigurationDir("target/test-classes");
+ PolicyControllerConstants.getFactory().destroy();
HttpClientFactoryInstance.getClientFactory().build(
BusTopicParams.builder()
@@ -70,8 +114,16 @@ public class RestLifecycleManagerTest {
server.addServletClass("/*", RestLifecycleManager.class.getName());
server.waitedStart(5000L);
- Assert.assertTrue(NetworkUtil.isTcpPortOpen("localhost", 8765, 5, 10000L));
+ assertTrue(NetworkUtil.isTcpPortOpen("localhost", 8765, 5, 10000L));
+
+ controllerSupport.installArtifact();
+ Properties noopTopicProperties = new Properties();
+ noopTopicProperties.put(PolicyEndPointProperties.PROPERTY_NOOP_SOURCE_TOPICS, "DCAE_TOPIC");
+ noopTopicProperties.put(PolicyEndPointProperties.PROPERTY_NOOP_SINK_TOPICS, "APPC-CL");
+ TopicEndpointManager.getManager().addTopics(noopTopicProperties);
+
+ client = HttpClientFactoryInstance.getClientFactory().get("lifecycle");
}
/**
@@ -79,88 +131,287 @@ public class RestLifecycleManagerTest {
*/
@After
public void tearDown() {
- HttpServletServerFactoryInstance.getServerFactory().destroy();
+ fsm.shutdown();
+
+ NoopTopicFactories.getSourceFactory().destroy();
+ NoopTopicFactories.getSinkFactory().destroy();
+
HttpClientFactoryInstance.getClientFactory().destroy();
+ HttpServletServerFactoryInstance.getServerFactory().destroy();
+
+ PolicyControllerConstants.getFactory().destroy();
+ SystemPersistenceConstants.getManager().setConfigurationDir(null);
}
@Test
- public void testFsm() {
+ public void testMultiPolicyFlow() throws IOException, CoderException {
+ /* group assignments */
- HttpClient client = HttpClientFactoryInstance.getClientFactory().get("lifecycle");
- Response response;
+ group();
+ subgroup();
- /* group */
+ /* other resources */
- response = client.put("group/GG", Entity.json(""), Collections.emptyMap());
- assertEquals(Status.OK.getStatusCode(), response.getStatus());
- assertEquals("GG", HttpClient.getBody(response, String.class));
+ properties();
+ topics();
- response = HttpClientFactoryInstance.getClientFactory().get("lifecycle").get("group");
- assertEquals(Status.OK.getStatusCode(), response.getStatus());
- assertEquals(LifecycleFeature.fsm.getGroup(), HttpClient.getBody(response, String.class));
+ /* status interval */
- /* subgroup */
+ status();
- response = client.put("subgroup/YY", Entity.json(""), Collections.emptyMap());
- assertEquals(Status.OK.getStatusCode(), response.getStatus());
- assertEquals("YY", HttpClient.getBody(response, String.class));
+ /* start up configuration */
- response = client.get("subgroup");
- assertEquals(Status.OK.getStatusCode(), response.getStatus());
- assertEquals(LifecycleFeature.fsm.getSubgroup(), HttpClient.getBody(response, String.class));
+ resourceLists("policyTypes", 2);
+ get("policyTypes/onap.policies.native.drools.Artifact/1.0.0", Status.OK.getStatusCode());
+ get("policyTypes/onap.policies.native.drools.Controller/1.0.0", Status.OK.getStatusCode());
+ get("policyTypes/onap.policies.controlloop.Operational/1.0.0", Status.NOT_FOUND.getStatusCode());
+ get("policyTypes/onap.policies.controlloop.operational.common.Drools/1.0.0", Status.NOT_FOUND.getStatusCode());
- /* properties */
+ resourceLists("policies", 0);
+ get("policies/example.controller/1.0.0", Status.NOT_FOUND.getStatusCode());
+ get("policies/example.artifact/1.0.0", Status.NOT_FOUND.getStatusCode());
- response = client.get("properties");
- assertEquals(Status.OK.getStatusCode(), response.getStatus());
- assertEquals(LifecycleFeature.fsm.getProperties(), HttpClient.getBody(response, Properties.class));
+ /* start lifecycle */
- /* state (disallowed state change as has not been started) */
+ assertTrue(fsm.start());
- response = client.put("state/PASSIVE", Entity.json(""), Collections.emptyMap());
- assertEquals(Status.OK.getStatusCode(), response.getStatus());
- assertEquals(Boolean.FALSE, HttpClient.getBody(response, Boolean.class));
+ booleanPut("state/ACTIVE", "", Status.OK.getStatusCode(), Boolean.TRUE);
+ assertEquals(PdpState.ACTIVE,
+ HttpClient.getBody(get("state", Status.OK.getStatusCode()), PdpState.class));
- response = client.get("state");
- assertEquals(Status.OK.getStatusCode(), response.getStatus());
- assertEquals(PdpState.TERMINATED, HttpClient.getBody(response, PdpState.class));
+ /* add native controller policy */
- /* topics */
+ ToscaPolicy nativeControllerPolicy =
+ getPolicyFromFile(EXAMPLE_NATIVE_CONTROLLER_POLICY_JSON, EXAMPLE_NATIVE_CONTROLLER_POLICY_NAME);
+ booleanPost("policies", toString(nativeControllerPolicy), Status.OK.getStatusCode(), Boolean.TRUE);
- assertEquals(Status.OK.getStatusCode(), client.get("topic/source").getStatus());
- assertEquals(Status.OK.getStatusCode(), client.get("topic/sink").getStatus());
+ assertTrue(PolicyControllerConstants.getFactory().get("lifecycle").isAlive());
+ assertFalse(PolicyControllerConstants.getFactory().get("lifecycle").getDrools().isBrained());
+ assertFalse(PolicyControllerConstants.getFactory().get("lifecycle").getDrools().isAlive());
- /* status interval */
+ get("policyTypes/onap.policies.controlloop.Operational/1.0.0", Status.NOT_FOUND.getStatusCode());
+ get("policyTypes/onap.policies.controlloop.operational.common.Drools/1.0.0", Status.NOT_FOUND.getStatusCode());
+
+ resourceLists("policies", 1);
+ get("policies/example.controller/1.0.0", Status.OK.getStatusCode());
+
+ /* add native artifact policy */
+
+ ToscaPolicy nativeArtifactPolicy =
+ getPolicyFromFile(EXAMPLE_NATIVE_ARTIFACT_POLICY_JSON, EXAMPLE_NATIVE_ARTIFACT_POLICY_NAME);
+ booleanPost("policies", toString(nativeArtifactPolicy), Status.OK.getStatusCode(), Boolean.TRUE);
+
+ assertTrue(PolicyControllerConstants.getFactory().get("lifecycle").isAlive());
+ assertTrue(PolicyControllerConstants.getFactory().get("lifecycle").getDrools().isBrained());
+ assertTrue(PolicyControllerConstants.getFactory().get("lifecycle").getDrools().isAlive());
+
+ /* verify new supported operational policy types */
+
+ resourceLists("policyTypes", 5);
+ get("policyTypes/onap.policies.native.drools.Artifact/1.0.0", Status.OK.getStatusCode());
+ get("policyTypes/onap.policies.native.drools.Controller/1.0.0", Status.OK.getStatusCode());
+ get("policyTypes/onap.policies.controlloop.Operational/1.0.0", Status.OK.getStatusCode());
+ get("policyTypes/onap.policies.controlloop.operational.common.Drools/1.0.0", Status.OK.getStatusCode());
+ get("policyTypes/onap.policies.type1.type2/1.0.0", Status.OK.getStatusCode());
+
+ /* verify controller and artifact policies */
+
+ resourceLists("policies", 2);
+ get("policies/example.controller/1.0.0", Status.OK.getStatusCode());
+ get("policies/example.artifact/1.0.0", Status.OK.getStatusCode());
+
+ /* add tosca compliant operational policy */
+
+ ToscaPolicy opPolicy = getExamplesPolicy(VCPE_OPERATIONAL_DROOLS_POLICY_JSON, OP_POLICY_NAME_VCPE);
+ opPolicy.getProperties().put("controllerName", "lifecycle");
+ if (StringUtils.isBlank(opPolicy.getName())) {
+ opPolicy.setName(opPolicy.getMetadata().get("policy-id"));
+ }
+
+ booleanPost("policies", toString(opPolicy), Status.OK.getStatusCode(), Boolean.TRUE);
+ assertTrue(PolicyControllerConstants.getFactory().get("lifecycle").isAlive());
+ assertTrue(PolicyControllerConstants.getFactory().get("lifecycle").getDrools().isBrained());
+ assertEquals(1,
+ PolicyControllerConstants
+ .getFactory().get("lifecycle").getDrools().facts("junits", ToscaPolicy.class) .size());
+
+ resourceLists("policies", 3);
+ get("policies/" + opPolicy.getName() + "/" + opPolicy.getVersion(), Status.OK.getStatusCode());
+ get("policies/example.controller/1.0.0", Status.OK.getStatusCode());
+ get("policies/example.artifact/1.0.0", Status.OK.getStatusCode());
+
+ booleanDelete("policies/" + opPolicy.getName() + "/" + opPolicy.getVersion(),
+ Status.OK.getStatusCode(), Boolean.TRUE);
+ assertEquals(0,
+ PolicyControllerConstants
+ .getFactory().get("lifecycle").getDrools().facts("junits", ToscaPolicy.class) .size());
- response = client.put("status/interval/1000", Entity.json(""), Collections.emptyMap());
+ resourceLists("policies", 2);
+ get("policies/" + opPolicy.getName() + "/" + opPolicy.getVersion(), Status.NOT_FOUND.getStatusCode());
+ get("policies/example.controller/1.0.0", Status.OK.getStatusCode());
+ get("policies/example.artifact/1.0.0", Status.OK.getStatusCode());
+
+ /* individual deploy/undeploy operations */
+
+ resourceLists("policies/operations", 2);
+
+ booleanPost("policies/operations/deployment", toString(opPolicy), Status.OK.getStatusCode(), Boolean.TRUE);
+ assertEquals(1,
+ PolicyControllerConstants
+ .getFactory().get("lifecycle").getDrools().facts("junits", ToscaPolicy.class) .size());
+
+ resourceLists("policies", 2);
+ get("policies/" + opPolicy.getName() + "/" + opPolicy.getVersion(), Status.NOT_FOUND.getStatusCode());
+ get("policies/example.controller/1.0.0", Status.OK.getStatusCode());
+ get("policies/example.artifact/1.0.0", Status.OK.getStatusCode());
+
+ booleanPost(
+ "policies/operations/undeployment", toString(opPolicy), Status.OK.getStatusCode(), Boolean.TRUE);
+ assertEquals(0,
+ PolicyControllerConstants
+ .getFactory().get("lifecycle").getDrools().facts("junits", ToscaPolicy.class) .size());
+
+ resourceLists("policies", 2);
+ get("policies/" + opPolicy.getName() + "/" + opPolicy.getVersion(), Status.NOT_FOUND.getStatusCode());
+ get("policies/example.controller/1.0.0", Status.OK.getStatusCode());
+ get("policies/example.artifact/1.0.0", Status.OK.getStatusCode());
+
+ /* delete native artifact policy */
+
+ booleanDelete("policies/example.artifact/1.0.0", Status.OK.getStatusCode(), Boolean.TRUE);
+ assertTrue(PolicyControllerConstants.getFactory().get("lifecycle").isAlive());
+ assertFalse(PolicyControllerConstants.getFactory().get("lifecycle").getDrools().isBrained());
+
+ resourceLists("policyTypes", 2);
+ get("policyTypes/onap.policies.native.drools.Artifact/1.0.0", Status.OK.getStatusCode());
+ get("policyTypes/onap.policies.native.drools.Controller/1.0.0", Status.OK.getStatusCode());
+ get("policyTypes/onap.policies.controlloop.Operational/1.0.0", Status.NOT_FOUND.getStatusCode());
+ get("policyTypes/onap.policies.controlloop.operational.common.Drools/1.0.0", Status.NOT_FOUND.getStatusCode());
+ get("policyTypes/onap.policies.type1.type2/1.0.0", Status.NOT_FOUND.getStatusCode());
+
+ resourceLists("policies", 1);
+ get("policies/" + opPolicy.getName() + "/" + opPolicy.getVersion(), Status.NOT_FOUND.getStatusCode());
+ get("policies/example.artifact/1.0.0", Status.NOT_FOUND.getStatusCode());
+ get("policies/example.controller/1.0.0", Status.OK.getStatusCode());
+
+ /* delete native controller policy */
+
+ booleanDelete("policies/example.controller/1.0.0", Status.OK.getStatusCode(), Boolean.TRUE);
+
+ resourceLists("policyTypes", 2);
+ get("policyTypes/onap.policies.native.drools.Artifact/1.0.0", Status.OK.getStatusCode());
+ get("policyTypes/onap.policies.native.drools.Controller/1.0.0", Status.OK.getStatusCode());
+ get("policyTypes/onap.policies.controlloop.Operational/1.0.0", Status.NOT_FOUND.getStatusCode());
+ get("policyTypes/onap.policies.controlloop.operational.common.Drools/1.0.0", Status.NOT_FOUND.getStatusCode());
+ get("policyTypes/onap.policies.type1.type2/1.0.0", Status.NOT_FOUND.getStatusCode());
+
+ resourceLists("policies", 0);
+ get("policies/" + opPolicy.getName() + "/" + opPolicy.getVersion(), Status.NOT_FOUND.getStatusCode());
+ get("policies/example.artifact/1.0.0", Status.NOT_FOUND.getStatusCode());
+ get("policies/example.controller/1.0.0", Status.NOT_FOUND.getStatusCode());
+
+ assertThatIllegalArgumentException().isThrownBy(() -> PolicyControllerConstants.getFactory().get("lifecycle"));
+ }
+
+ private Response get(String contextPath, int statusCode) {
+ Response response = client.get(contextPath);
+ assertEquals(statusCode, response.getStatus());
+ return response;
+ }
+
+ private void booleanResponse(Response response, int statusCode, Boolean bool) {
+ assertEquals(statusCode, response.getStatus());
+ assertEquals(bool, HttpClient.getBody(response, Boolean.class));
+ }
+
+ private void booleanPut(String contextPath, String body, int statusCode, Boolean bool) {
+ Response response = client.put(contextPath, Entity.json(body), Collections.emptyMap());
+ booleanResponse(response, statusCode, bool);
+ }
+
+ private void booleanPost(String contextPath, String body, int statusCode, Boolean bool) {
+ Response response = client.post(contextPath, Entity.json(body), Collections.emptyMap());
+ booleanResponse(response, statusCode, bool);
+ }
+
+ private void booleanDelete(String contextPath, int statusCode, Boolean bool) {
+ Response response = client.delete(contextPath, Collections.emptyMap());
+ booleanResponse(response, statusCode, bool);
+ }
+
+ private void resourceLists(String resource, int size) {
+ Response response = client.get(resource);
+ assertEquals(Status.OK.getStatusCode(), response.getStatus());
+ assertEquals(size, HttpClient.getBody(response, List.class).size());
+ }
+
+ private void status() {
+ Response response = client.put("status/interval/240", Entity.json(""), Collections.emptyMap());
assertEquals(Status.OK.getStatusCode(), response.getStatus());
- assertEquals(Long.valueOf(1000L), HttpClient.getBody(response, Long.class));
+ assertEquals(Long.valueOf(240L), HttpClient.getBody(response, Long.class));
response = client.get("status/interval");
assertEquals(Status.OK.getStatusCode(), response.getStatus());
- assertEquals(Long.valueOf(1000L), HttpClient.getBody(response, Long.class));
+ assertEquals(Long.valueOf(240L), HttpClient.getBody(response, Long.class));
+ }
- /* policy types */
+ private void topics() {
+ assertEquals(Status.OK.getStatusCode(), client.get("topic/source").getStatus());
+ assertEquals(Status.OK.getStatusCode(), client.get("topic/sink").getStatus());
+ }
- response = client.get("policyTypes");
+ private void properties() {
+ Response response = client.get("properties");
assertEquals(Status.OK.getStatusCode(), response.getStatus());
- assertEquals(2, HttpClient.getBody(response, List.class).size());
+ assertEquals(fsm.getProperties(), HttpClient.getBody(response, Properties.class));
+ }
- response = client.get("policyTypes/onap.policies.native.drools.Artifact/1.0.0");
+ private void subgroup() {
+ Response response = client.put("subgroup/YY", Entity.json(""), Collections.emptyMap());
assertEquals(Status.OK.getStatusCode(), response.getStatus());
- assertNotNull(HttpClient.getBody(response, String.class));
+ assertEquals("YY", HttpClient.getBody(response, String.class));
- response = client.get("policyTypes/onap.policies.native.drools.Controller/1.0.0");
+ response = client.get("subgroup");
assertEquals(Status.OK.getStatusCode(), response.getStatus());
- assertNotNull(HttpClient.getBody(response, String.class));
+ assertEquals("YY", HttpClient.getBody(response, String.class));
+ }
- /* policies */
+ private void group() {
+ Response response = client.put("group/GG", Entity.json(""), Collections.emptyMap());
+ assertEquals(Status.OK.getStatusCode(), response.getStatus());
+ assertEquals("GG", HttpClient.getBody(response, String.class));
- response = client.get("policies");
+ response = HttpClientFactoryInstance.getClientFactory().get("lifecycle").get("group");
assertEquals(Status.OK.getStatusCode(), response.getStatus());
- assertEquals(0, HttpClient.getBody(response, List.class).size());
+ assertEquals("GG", HttpClient.getBody(response, String.class));
+ }
+
+ private LifecycleFsm newFsmInstance() throws NoSuchFieldException, IllegalAccessException {
+ Field fsmField = LifecycleFeature.class.getDeclaredField("fsm");
+ fsmField.setAccessible(true);
+
+ Field modifiers = Field.class.getDeclaredField("modifiers");
+ modifiers.setAccessible(true);
+ modifiers.setInt(fsmField, fsmField.getModifiers() & ~Modifier.FINAL );
+
+ LifecycleFsm fsm = new LifecycleFsm();
+ fsmField.set(null, fsm);
+ return fsm;
+ }
+
+ protected ToscaPolicy getPolicyFromFile(String filePath, String policyName) throws CoderException, IOException {
+ String policyJson = Files.readString(Paths.get(filePath));
+ ToscaServiceTemplate serviceTemplate = coder.decode(policyJson, ToscaServiceTemplate.class);
+ return serviceTemplate.getToscaTopologyTemplate().getPolicies().get(0).get(policyName);
+ }
+
+ protected String toString(ToscaPolicy policy) throws CoderException {
+ return coder.encode(policy);
+ }
- response = client.get("policies/onap.policies.controlloop.Operational");
- assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
+ private ToscaPolicy getExamplesPolicy(String resourcePath, String policyName) throws CoderException {
+ String policyJson = ResourceUtils.getResourceAsString(resourcePath);
+ ToscaServiceTemplate serviceTemplate = new StandardCoder().decode(policyJson, ToscaServiceTemplate.class);
+ return serviceTemplate.getToscaTopologyTemplate().getPolicies().get(0).get(policyName);
}
}
diff --git a/feature-lifecycle/src/test/resources/lifecycle.kmodule b/feature-lifecycle/src/test/resources/lifecycle.kmodule
index 8bf1ed5a..2e5235c7 100644
--- a/feature-lifecycle/src/test/resources/lifecycle.kmodule
+++ b/feature-lifecycle/src/test/resources/lifecycle.kmodule
@@ -20,7 +20,10 @@
-->
<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule">
- <kbase name="onap.policies.type1.type2">
+ <kbase name="onap.policies.controlloop.Operational" default="false" equalsBehavior="equality"/>
+ <kbase name="onap.policies.controlloop.operational.common.Drools" default="false" equalsBehavior="equality"
+ includes="onap.policies.controlloop.Operational"/>
+ <kbase name="onap.policies.type1.type2" includes="onap.policies.controlloop.operational.common.Drools">
<ksession name="junits" />
</kbase>
</kmodule>
diff --git a/policy-management/src/main/java/org/onap/policy/drools/features/PolicyControllerFeatureApi.java b/policy-management/src/main/java/org/onap/policy/drools/features/PolicyControllerFeatureApi.java
index 49287786..d11863f0 100644
--- a/policy-management/src/main/java/org/onap/policy/drools/features/PolicyControllerFeatureApi.java
+++ b/policy-management/src/main/java/org/onap/policy/drools/features/PolicyControllerFeatureApi.java
@@ -108,7 +108,8 @@ public interface PolicyControllerFeatureApi extends OrderedService {
* of the operation preventing the invocation of
* lower priority features. False, otherwise.
*/
- default boolean beforePatch(PolicyController controller, DroolsConfiguration configuration) {
+ default boolean beforePatch(
+ PolicyController controller, DroolsConfiguration oldConfiguration, DroolsConfiguration newConfiguration) {
return false;
}
@@ -119,7 +120,9 @@ public interface PolicyControllerFeatureApi extends OrderedService {
* of the operation preventing the invocation of
* lower priority features. False, otherwise.
*/
- default boolean afterPatch(PolicyController controller, boolean success) {
+ default boolean afterPatch(
+ PolicyController controller, DroolsConfiguration oldConfiguration,
+ DroolsConfiguration newConfiguration, boolean success) {
return false;
}
diff --git a/policy-management/src/main/java/org/onap/policy/drools/system/internal/AggregatedPolicyController.java b/policy-management/src/main/java/org/onap/policy/drools/system/internal/AggregatedPolicyController.java
index b80f4c86..0c12dbcb 100644
--- a/policy-management/src/main/java/org/onap/policy/drools/system/internal/AggregatedPolicyController.java
+++ b/policy-management/src/main/java/org/onap/policy/drools/system/internal/AggregatedPolicyController.java
@@ -227,7 +227,7 @@ public class AggregatedPolicyController implements PolicyController, TopicListen
}
if (FeatureApiUtils.apply(getProviders(),
- feature -> feature.beforePatch(this, newDroolsConfiguration),
+ feature -> feature.beforePatch(this, oldDroolsConfiguration, newDroolsConfiguration),
(feature, ex) -> logger.error("{}: feature {} before-patch failure because of {}", this,
feature.getClass().getName(), ex.getMessage(), ex))) {
return true;
@@ -268,7 +268,7 @@ public class AggregatedPolicyController implements PolicyController, TopicListen
boolean finalSuccess = success;
FeatureApiUtils.apply(getProviders(),
- feature -> feature.afterPatch(this, finalSuccess),
+ feature -> feature.afterPatch(this, oldDroolsConfiguration, newDroolsConfiguration, finalSuccess),
(feature, ex) -> logger.error("{}: feature {} after-patch failure because of {}", this,
feature.getClass().getName(), ex.getMessage(), ex));