summaryrefslogtreecommitdiffstats
path: root/feature-lifecycle/src/main
diff options
context:
space:
mode:
authorjhh <jorge.hernandez-herrero@att.com>2020-03-22 19:37:21 -0500
committerjhh <jorge.hernandez-herrero@att.com>2020-03-22 22:29:07 -0500
commit97e19c931535a5b474d4942a9982f0b7a1cf7414 (patch)
treeea2f83efb976bf7bda159097dbff50c0b99e451a /feature-lifecycle/src/main
parentcc69c5a3f56a3e90c17c4fdcf38dc93c37cf93f2 (diff)
Fix op policies distribution to controllers
Fix a bug when distributing a policy to the right controller plus additional junits to catch similar issues. Issue-ID: POLICY-2356 Signed-off-by: jhh <jorge.hernandez-herrero@att.com> Change-Id: I25fefa64ad54c55e6516ae18c6895b6de9407419 Signed-off-by: jhh <jorge.hernandez-herrero@att.com>
Diffstat (limited to 'feature-lifecycle/src/main')
-rw-r--r--feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleFsm.java42
-rw-r--r--feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/PolicyTypeDroolsController.java63
-rw-r--r--feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/PolicyTypeNativeArtifactController.java2
-rw-r--r--feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/PolicyTypeNativeDroolsController.java21
-rw-r--r--feature-lifecycle/src/main/java/org/onap/policy/drools/server/restful/RestLifecycleManager.java225
5 files changed, 307 insertions, 46 deletions
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 a435f02e..6953d831 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
@@ -68,24 +68,32 @@ import org.slf4j.LoggerFactory;
*/
public class LifecycleFsm implements Startable {
+ /**
+ * Default Status Timer in seconds.
+ */
+ public static final long DEFAULT_STATUS_TIMER_SECONDS = 120L;
+
private static final Logger logger = LoggerFactory.getLogger(LifecycleFsm.class);
protected static final String CONFIGURATION_PROPERTIES_NAME = "feature-lifecycle";
protected static final String GROUP_NAME = "lifecycle.pdp.group";
protected static final String DEFAULT_PDP_GROUP = "defaultGroup";
- protected static final long DEFAULT_STATUS_TIMER_SECONDS = 120L;
protected static final long MIN_STATUS_INTERVAL_SECONDS = 5L;
protected static final String PDP_MESSAGE_NAME = "messageName";
protected static final ToscaPolicyTypeIdentifier POLICY_TYPE_DROOLS_NATIVE_RULES =
- new ToscaPolicyTypeIdentifier("onap.policies.native.Drools", "1.0.0");
+ new ToscaPolicyTypeIdentifier("onap.policies.native.drools.Artifact", "1.0.0");
- protected static final ToscaPolicyTypeIdentifier POLICY_TYPE_DROOLS_CONTROLLER =
- new ToscaPolicyTypeIdentifier("onap.policies.drools.Controller", "1.0.0");
+ protected static final ToscaPolicyTypeIdentifier POLICY_TYPE_DROOLS_NATIVE_CONTROLLER =
+ new ToscaPolicyTypeIdentifier("onap.policies.native.drools.Controller", "1.0.0");
+ @Getter
protected final Properties properties;
+ @Getter
protected TopicSource source;
+
+ @Getter
protected TopicSinkClient client;
@Getter
@@ -113,14 +121,17 @@ public class LifecycleFsm implements Startable {
protected long statusTimerSeconds = DEFAULT_STATUS_TIMER_SECONDS;
@Getter
- private final String group;
+ @Setter
+ private String group;
@Getter
+ @Setter
protected String subgroup;
@Getter
protected final Map<ToscaPolicyTypeIdentifier, PolicyTypeController> policyTypesMap = new HashMap<>();
+ @Getter
protected final Map<ToscaPolicyIdentifier, ToscaPolicy> policiesMap = new HashMap<>();
/**
@@ -130,9 +141,8 @@ public class LifecycleFsm implements Startable {
this.properties = SystemPersistenceConstants.getManager().getProperties(CONFIGURATION_PROPERTIES_NAME);
this.group = this.properties.getProperty(GROUP_NAME, DEFAULT_PDP_GROUP);
- this.policyTypesMap.put(
- POLICY_TYPE_DROOLS_CONTROLLER,
- new PolicyTypeNativeDroolsController(this, POLICY_TYPE_DROOLS_CONTROLLER));
+ this.policyTypesMap.put(POLICY_TYPE_DROOLS_NATIVE_CONTROLLER,
+ new PolicyTypeNativeDroolsController(this, POLICY_TYPE_DROOLS_NATIVE_CONTROLLER));
this.policyTypesMap.put(
POLICY_TYPE_DROOLS_NATIVE_RULES,
new PolicyTypeNativeArtifactController(this, POLICY_TYPE_DROOLS_NATIVE_RULES));
@@ -171,7 +181,12 @@ public class LifecycleFsm implements Startable {
logger.info("lifecycle event: start controller: {}", controller.getName());
for (ToscaPolicyTypeIdentifier id : controller.getPolicyTypes()) {
if (isToscaPolicyType(id.getName())) {
- policyTypesMap.put(id, new PolicyTypeDroolsController(this, id, controller));
+ PolicyTypeDroolsController ptDroolsController = (PolicyTypeDroolsController) policyTypesMap.get(id);
+ if (ptDroolsController == null) {
+ policyTypesMap.put(id, new PolicyTypeDroolsController(this, id, controller));
+ } else {
+ ptDroolsController.add(controller);
+ }
}
}
}
@@ -188,7 +203,14 @@ 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()) {
- policyTypesMap.remove(id);
+ if (!policyTypesMap.containsKey(id)) {
+ continue;
+ }
+ PolicyTypeDroolsController ptDroolsController = (PolicyTypeDroolsController) policyTypesMap.get(id);
+ ptDroolsController.remove(controller);
+ if (ptDroolsController.controllers().isEmpty()) {
+ policyTypesMap.remove(id);
+ }
}
}
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 36c52e2b..2772d854 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
@@ -26,6 +26,7 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import lombok.Getter;
+import lombok.NonNull;
import org.apache.commons.lang3.StringUtils;
import org.onap.policy.common.gson.annotation.GsonJsonIgnore;
import org.onap.policy.common.utils.coder.CoderException;
@@ -71,15 +72,53 @@ public class PolicyTypeDroolsController implements PolicyTypeController {
}
@Override
- public boolean deploy(ToscaPolicy policy) {
+ public boolean deploy(@NonNull ToscaPolicy policy) {
return perform(policy, (PolicyController controller) -> controller.offer(policy));
}
+ /**
+ * Adds a controller to support this policy type.
+ */
+ public void add(@NonNull PolicyController controller) {
+ if (!controller.getPolicyTypes().contains(this.policyType)) {
+ throw new IllegalArgumentException(
+ "controller " + controller.getName() + " does not support " + this.policyType);
+ }
+ controllers.put(controller.getName(), controller);
+ }
+
+ /**
+ * Removes a controller from this policy type.
+ */
+ public void remove(@NonNull PolicyController controller) {
+ controllers.remove(controller.getName());
+ }
+
@Override
- public boolean undeploy(ToscaPolicy policy) {
+ public boolean undeploy(@NonNull ToscaPolicy policy) {
return perform(policy, (PolicyController controller) -> controller.getDrools().delete(policy));
}
+ /**
+ * Get all controllers that support the policy type.
+ */
+ public List<PolicyController> controllers() {
+ return List.copyOf(controllers.values());
+ }
+
+ private List<PolicyController> controllers(String controllerName) {
+ if (StringUtils.isBlank(controllerName)) {
+ /* this policy applies to all controllers */
+ return controllers();
+ }
+
+ if (!this.controllers.containsKey(controllerName)) {
+ return List.of();
+ }
+
+ return List.of(this.controllers.get(controllerName));
+ }
+
private boolean perform(ToscaPolicy policy, Function<PolicyController, Boolean> operation) {
try {
List<PolicyController> selected = selectControllers(policy);
@@ -116,24 +155,4 @@ public class PolicyTypeDroolsController implements PolicyTypeController {
}
return selected;
}
-
- private List<PolicyController> controllers(String controllerName) {
- if (StringUtils.isBlank(controllerName)) {
- /* this policy applies to all controllers */
- return controllers();
- }
-
- if (!this.controllers.containsKey(controllerName)) {
- return List.of();
- }
-
- return List.of(this.controllers.get(controllerName));
- }
-
- /**
- * Get all controllers that support the policy type.
- */
- public List<PolicyController> controllers() {
- return List.copyOf(controllers.values());
- }
}
diff --git a/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/PolicyTypeNativeArtifactController.java b/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/PolicyTypeNativeArtifactController.java
index 31e9059d..d91ecccf 100644
--- a/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/PolicyTypeNativeArtifactController.java
+++ b/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/PolicyTypeNativeArtifactController.java
@@ -57,7 +57,7 @@ public class PolicyTypeNativeArtifactController implements PolicyTypeController
nativePolicy = fsm.getDomainMaker().convertTo(policy, NativeArtifactPolicy.class);
controller =
PolicyControllerConstants.getFactory().get(nativePolicy.getProperties().getController().getName());
- } catch (CoderException e) {
+ } catch (CoderException | RuntimeException e) {
logger.warn("Invalid Policy: {}", policy);
return false;
}
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 b0118fbe..2a417dcb 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
@@ -21,6 +21,7 @@
package org.onap.policy.drools.lifecycle;
import com.fasterxml.jackson.annotation.JsonIgnore;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Properties;
@@ -142,6 +143,10 @@ public class PolicyTypeNativeDroolsController implements PolicyTypeController {
}
private boolean configControllerSources(ControllerProperties controllerConfig, Properties controllerProps) {
+ if (controllerConfig.getSourceTopics() == null) {
+ return true;
+ }
+
for (ControllerSourceTopic configSourceTopic : controllerConfig.getSourceTopics()) {
List<TopicSource> sources =
TopicEndpointManager.getManager().getTopicSources(List.of(configSourceTopic.getTopicName()));
@@ -161,6 +166,10 @@ public class PolicyTypeNativeDroolsController implements PolicyTypeController {
}
private boolean configControllerSinks(ControllerProperties controllerConfig, Properties controllerProps) {
+ if (controllerConfig.getSinkTopics() == null) {
+ return true;
+ }
+
for (ControllerSinkTopic configSinkTopic : controllerConfig.getSinkTopics()) {
List<TopicSink> sinks =
TopicEndpointManager.getManager().getTopicSinks(List.of(configSinkTopic.getTopicName()));
@@ -236,13 +245,21 @@ public class PolicyTypeNativeDroolsController implements PolicyTypeController {
}
private List<String> sourceTopics(List<ControllerSourceTopic> sourceTopics) {
+ if (sourceTopics == null) {
+ return Collections.EMPTY_LIST;
+ }
+
return sourceTopics.stream()
.map(ControllerSourceTopic::getTopicName)
.collect(Collectors.toList());
}
- private List<String> sinkTopics(List<ControllerSinkTopic> sourceTopics) {
- return sourceTopics.stream()
+ private List<String> sinkTopics(List<ControllerSinkTopic> sinkTopics) {
+ if (sinkTopics == null) {
+ return Collections.EMPTY_LIST;
+ }
+
+ return sinkTopics.stream()
.map(ControllerSinkTopic::getTopicName)
.collect(Collectors.toList());
}
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 44113779..3e55a10c 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
@@ -20,47 +20,250 @@ 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.Properties;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
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.drools.lifecycle.LifecycleFeature;
-import org.onap.policy.drools.lifecycle.LifecycleFsm;
+import org.onap.policy.drools.lifecycle.PolicyTypeController;
+import org.onap.policy.models.pdp.concepts.PdpStateChange;
+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.ToscaPolicyTypeIdentifier;
/**
* REST Lifecycle Manager.
*/
-@Path("/policy/pdp")
+@Path("/policy/pdp/engine/lifecycle")
@Produces({MediaType.APPLICATION_JSON, YamlMessageBodyHandler.APPLICATION_YAML})
@Consumes({MediaType.APPLICATION_JSON, YamlMessageBodyHandler.APPLICATION_YAML})
@Api
public class RestLifecycleManager {
+ /**
+ * GET group.
+ */
+
@GET
- @Path("engine/lifecycle/fsm/group")
- @ApiOperation(value = "Retrieves the Lifecycle FSM",
- notes = "Lifecycle FSM", response = LifecycleFsm.class)
+ @Path("group")
+ @ApiOperation(value = "Retrieves the Lifecycle group",
+ notes = "Lifecycle Group", response = String.class)
public Response group() {
return Response.status(Response.Status.OK).entity(LifecycleFeature.fsm.getGroup()).build();
}
+ /**
+ * PUT group.
+ */
+
+ @PUT
+ @Path("group/{group}")
+ @ApiOperation(value = "Updates the Lifecycle group",
+ notes = "Lifecycle Group", response = String.class)
+ public Response updateGroup(
+ @ApiParam(value = "Group", required = true) @PathParam("group") String group) {
+ LifecycleFeature.fsm.setGroup(group);
+ return Response.status(Response.Status.OK).entity(LifecycleFeature.fsm.getGroup()).build();
+ }
+
+ /**
+ * GET subgroup.
+ */
+
@GET
- @Path("engine/lifecycle/fsm/subgroup")
- @ApiOperation(value = "Retrieves the Lifecycle FSM",
- notes = "Lifecycle FSM", response = LifecycleFsm.class)
+ @Path("subgroup")
+ @ApiOperation(value = "Retrieves the Lifecycle subgroup",
+ notes = "Lifecycle Subgroup", response = String.class)
public Response subgroup() {
return Response.status(Response.Status.OK).entity(LifecycleFeature.fsm.getSubgroup()).build();
}
+ /**
+ * PUT subgroup.
+ */
+
+ @PUT
+ @Path("subgroup/{subgroup}")
+ @ApiOperation(value = "Retrieves the Lifecycle subgroup",
+ notes = "Lifecycle Subgroup", response = String.class)
+ public Response subgroup(
+ @ApiParam(value = "Subgroup", required = true) @PathParam("subgroup") String subgroup) {
+ LifecycleFeature.fsm.setSubgroup(subgroup);
+ return Response.status(Response.Status.OK).entity(LifecycleFeature.fsm.getSubgroup()).build();
+ }
+
+ /**
+ * GET properties.
+ */
+
@GET
- @Path("engine/lifecycle/fsm/state")
- @ApiOperation(value = "Retrieves the Lifecycle FSM",
- notes = "Lifecycle FSM", response = LifecycleFsm.class)
+ @Path("properties")
+ @ApiOperation(value = "Retrieves the Lifecycle properties",
+ notes = "Lifecycle Properties", response = Properties.class)
+ public Response properties() {
+ return Response.status(Response.Status.OK).entity(LifecycleFeature.fsm.getProperties()).build();
+ }
+
+ /**
+ * GET state.
+ */
+
+ @GET
+ @Path("state")
+ @ApiOperation(value = "Retrieves the Lifecycle state", notes = "Lifecycle State", response = PdpState.class)
public Response state() {
return Response.status(Response.Status.OK).entity(LifecycleFeature.fsm.state()).build();
}
+
+ /**
+ * PUT state.
+ */
+
+ @PUT
+ @Path("state/{state}")
+ @ApiOperation(value = "updates the Lifecycle state", notes = "Lifecycle State", response = Boolean.class)
+ public Response updateState(
+ @ApiParam(value = "state", required = true) @PathParam("state") String state) {
+
+ PdpStateChange change = new PdpStateChange();
+ change.setPdpGroup(LifecycleFeature.fsm.getGroup());
+ change.setPdpSubgroup(LifecycleFeature.fsm.getSubgroup());
+ change.setState(PdpState.valueOf(state));
+ change.setName(LifecycleFeature.fsm.getName());
+
+ return Response.status(Response.Status.OK).entity(LifecycleFeature.fsm.stateChange(change)).build();
+ }
+
+ /**
+ * GET topic source.
+ */
+
+ @GET
+ @Path("topic/source")
+ @ApiOperation(value = "Retrieves the Lifecycle topic source",
+ notes = "Lifecycle Topic Source", response = TopicSource.class)
+ public Response source() {
+ return Response.status(Response.Status.OK).entity(LifecycleFeature.fsm.getSource()).build();
+ }
+
+ /**
+ * GET topic sink.
+ */
+
+ @GET
+ @Path("topic/sink")
+ @ApiOperation(value = "Retrieves the Lifecycle topic sink",
+ notes = "Lifecycle Topic Sink", response = TopicSink.class)
+ public Response sink() {
+ return Response.status(Response.Status.OK).entity(LifecycleFeature.fsm.getClient()).build();
+ }
+
+ /**
+ * GET status interval.
+ */
+
+ @GET
+ @Path("status/interval")
+ @ApiOperation(value = "Retrieves the Lifecycle Status Timer Interval in seconds",
+ notes = "Lifecycle Status Timer Interval in seconds", response = Long.class)
+ public Response updateStatusTimer() {
+ return Response.status(Response.Status.OK).entity(LifecycleFeature.fsm.getStatusTimerSeconds()).build();
+ }
+
+ /**
+ * PUT timeout.
+ */
+
+ @PUT
+ @Path("status/interval/{timeout}")
+ @ApiOperation(value = "Updates the Lifecycle Status Timer Interval in seconds",
+ notes = "Lifecycle Status Timer Interval in seconds", response = Long.class)
+ public Response statusTimer(
+ @ApiParam(value = "timeout", required = true) @PathParam("timeout") Long timeout) {
+ LifecycleFeature.fsm.setStatusTimerSeconds(timeout);
+ return Response.status(Response.Status.OK).entity(LifecycleFeature.fsm.getStatusTimerSeconds()).build();
+ }
+
+ /**
+ * GET policy types.
+ */
+
+ @GET
+ @Path("policyTypes")
+ @ApiOperation(value = "List of supported policy types",
+ notes = "Lifecycle Policy Types", responseContainer = "List")
+ public Response policyTypes() {
+ return Response.status(Response.Status.OK)
+ .entity(LifecycleFeature.fsm.getPolicyTypesMap().keySet())
+ .build();
+ }
+
+ /**
+ * GET controllers.
+ */
+
+ @GET
+ @Path("policyTypes/{policyType}/{policyVersion}")
+ @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) {
+ return Response.status(Response.Status.OK)
+ .entity(LifecycleFeature.fsm
+ .getPolicyTypesMap()
+ .get(new ToscaPolicyTypeIdentifier(policyType, policyVersion)))
+ .build();
+ }
+
+ /**
+ * GET policies.
+ */
+
+ @GET
+ @Path("policies")
+ @ApiOperation(value = "List of tracked policies",
+ notes = "Lifecycle Policies", responseContainer = "List")
+ public Response policies() {
+ return Response.status(Response.Status.OK)
+ .entity(LifecycleFeature.fsm.getPoliciesMap().keySet())
+ .build();
+
+ }
+
+ /**
+ * GET a policy.
+ */
+
+ @GET
+ @Path("policies/{policy}/{policyVersion}")
+ @ApiOperation(value = "Lifecycle tracked policy",
+ notes = "Lifecycle Tracked Policy", response = ToscaPolicy.class)
+ public Response policy(
+ @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();
+ }
+
+ return Response.status(Response.Status.NOT_FOUND).build();
+ }
}