summaryrefslogtreecommitdiffstats
path: root/feature-lifecycle/src/main
diff options
context:
space:
mode:
authorjhh <jorge.hernandez-herrero@att.com>2021-01-15 16:51:47 -0600
committerjhh <jorge.hernandez-herrero@att.com>2021-01-27 00:39:32 -0600
commit77d088a607c33c236bc41c58d9567e10299357a5 (patch)
treec35c7d92a58f49cc6d069910a4eab20a6bd08993 /feature-lifecycle/src/main
parent6d94c4ec33520776971c781c6ea6e80e6d0070b5 (diff)
sync policies when native artifact policies added
interoperability between native and non-native policies present several difficulties. The code submitted operates in deltas where deploy and undeploy operations are performed on the deltas of the updates. In order to support interoperability, policies not part of a delta update may need to be reapplied. For example, in the case when the delta is just a new native controller artifact, we should go through the set of already deployed policies and reapply non-native policies as long as the policy types that the native artifact policy supports. Issue-ID: POLICY-2762 Signed-off-by: jhh <jorge.hernandez-herrero@att.com> Change-Id: Ieb8e5e17862e9d607433a1d4e86a026725d73498 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/LifecycleFeature.java16
-rw-r--r--feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleFsm.java52
-rw-r--r--feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleStatePassive.java5
-rw-r--r--feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleStateRunning.java186
-rw-r--r--feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/PolicyTypeDroolsController.java29
-rw-r--r--feature-lifecycle/src/main/java/org/onap/policy/drools/server/restful/RestLifecycleManager.java64
6 files changed, 274 insertions, 78 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 003740c1..27d845b5 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
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* ONAP
* ================================================================================
- * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2019-2021 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.
@@ -20,6 +20,7 @@
package org.onap.policy.drools.lifecycle;
+import lombok.Getter;
import org.onap.policy.drools.features.DroolsControllerFeatureApi;
import org.onap.policy.drools.features.PolicyControllerFeatureApi;
import org.onap.policy.drools.features.PolicyEngineFeatureApi;
@@ -35,6 +36,7 @@ public class LifecycleFeature
/**
* Lifecycle FSM.
*/
+ @Getter
public static final LifecycleFsm fsm = new LifecycleFsm();
@Override
@@ -90,32 +92,32 @@ public class LifecycleFeature
}
private boolean fsmStart() {
- fsm.start();
+ getFsm().start();
return false;
}
private boolean fsmStart(PolicyController controller) {
- fsm.start(controller);
+ getFsm().start(controller);
return false;
}
private boolean fsmStop() {
- fsm.stop();
+ getFsm().stop();
return false;
}
private boolean fsmStop(PolicyController controller) {
- fsm.stop(controller);
+ getFsm().stop(controller);
return false;
}
private boolean fsmPatch(PolicyController controller) {
- fsm.patch(controller);
+ getFsm().patch(controller);
return false;
}
private boolean fsmShutdown() {
- fsm.shutdown();
+ getFsm().shutdown();
return false;
}
}
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 5478136f..d56e06e9 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
@@ -156,9 +156,7 @@ public class LifecycleFsm implements Startable {
String commaSeparatedPolicyTypes = this.properties.getProperty(MANDATORY_POLICY_TYPES);
if (!StringUtils.isBlank(commaSeparatedPolicyTypes)) {
- for (String mpt: commaSeparatedPolicyTypes.split("\\s*,\\s*")) {
- this.mandatoryPolicyTypes.add(mpt);
- }
+ Collections.addAll(this.mandatoryPolicyTypes, commaSeparatedPolicyTypes.split("\\s*,\\s*"));
}
logger.info("The mandatory Policy Types are {}. Compliance is {}",
@@ -347,7 +345,7 @@ public class LifecycleFsm implements Startable {
protected List<ToscaPolicy> getDeployablePoliciesAction(@NonNull List<ToscaPolicy> policies) {
List<ToscaPolicy> deployPolicies = new ArrayList<>(policies);
- deployPolicies.removeAll(policiesMap.values());
+ deployPolicies.removeAll(getActivePolicies());
// Ensure that the sequence of policy deployments is sane to minimize potential errors,
// First policies to deploy are the controller related ones, those that affect the lifecycle of
@@ -359,13 +357,12 @@ public class LifecycleFsm implements Startable {
Map<String, List<ToscaPolicy>> policyTypeGroups = groupPoliciesByPolicyType(deployPolicies);
// place native controller policies at the start of the list
- List<ToscaPolicy> orderedDeployableList =
- new ArrayList<>(policyTypeGroups.getOrDefault(POLICY_TYPE_DROOLS_NATIVE_CONTROLLER.getName(),
- Collections.EMPTY_LIST));
+ List<ToscaPolicy> orderedDeployableList = new ArrayList<>(
+ policyTypeGroups.getOrDefault(POLICY_TYPE_DROOLS_NATIVE_CONTROLLER.getName(), Collections.emptyList()));
// add to the working list the native controller policies
orderedDeployableList.addAll(
- policyTypeGroups.getOrDefault(POLICY_TYPE_DROOLS_NATIVE_RULES.getName(), Collections.EMPTY_LIST));
+ policyTypeGroups.getOrDefault(POLICY_TYPE_DROOLS_NATIVE_RULES.getName(), Collections.emptyList()));
// place non-native policies to place at the end of the list
orderedDeployableList.addAll(getNonNativePolicies(policyTypeGroups));
@@ -374,7 +371,7 @@ public class LifecycleFsm implements Startable {
}
protected List<ToscaPolicy> getUndeployablePoliciesAction(@NonNull List<ToscaPolicy> policies) {
- List<ToscaPolicy> undeployPolicies = new ArrayList<>(policiesMap.values());
+ List<ToscaPolicy> undeployPolicies = new ArrayList<>(getActivePolicies());
undeployPolicies.removeAll(policies);
if (undeployPolicies.isEmpty()) {
return undeployPolicies;
@@ -396,11 +393,11 @@ public class LifecycleFsm implements Startable {
// add to the working list the native rules policies if any
orderedUndeployableList.addAll(
- policyTypeGroups.getOrDefault(POLICY_TYPE_DROOLS_NATIVE_RULES.getName(), Collections.EMPTY_LIST));
+ policyTypeGroups.getOrDefault(POLICY_TYPE_DROOLS_NATIVE_RULES.getName(), Collections.emptyList()));
// finally add to the working list native controller policies if any
orderedUndeployableList.addAll(
- policyTypeGroups.getOrDefault(POLICY_TYPE_DROOLS_NATIVE_CONTROLLER.getName(), Collections.EMPTY_LIST));
+ policyTypeGroups.getOrDefault(POLICY_TYPE_DROOLS_NATIVE_CONTROLLER.getName(), Collections.emptyList()));
return orderedUndeployableList;
}
@@ -414,13 +411,13 @@ public class LifecycleFsm implements Startable {
}
protected List<ToscaPolicy> resetPoliciesAction() {
- List<ToscaPolicy> policies = new ArrayList<>(policiesMap.values());
+ List<ToscaPolicy> policies = new ArrayList<>(getActivePolicies());
policiesMap.clear();
return policies;
}
- protected boolean updatePoliciesAction(List<ToscaPolicy> toscaPolicies) {
- return (this.scheduler.submit(() -> state.updatePolicies(toscaPolicies)) != null);
+ protected void updatePoliciesAction(List<ToscaPolicy> toscaPolicies) {
+ this.scheduler.submit(() -> state.updatePolicies(toscaPolicies));
}
protected PolicyTypeController getController(ToscaConceptIdentifier policyType) {
@@ -428,7 +425,9 @@ public class LifecycleFsm implements Startable {
}
protected Map<String, List<ToscaPolicy>> groupPoliciesByPolicyType(List<ToscaPolicy> deployPolicies) {
- return deployPolicies.stream().collect(Collectors.groupingBy(policy -> policy.getTypeIdentifier().getName()));
+ return deployPolicies.stream()
+ .distinct()
+ .collect(Collectors.groupingBy(policy -> policy.getTypeIdentifier().getName()));
}
protected List<ToscaPolicy> getNonNativePolicies(@NonNull Map<String, List<ToscaPolicy>> policyTypeGroups) {
@@ -438,6 +437,25 @@ public class LifecycleFsm implements Startable {
.flatMap(entry -> entry.getValue().stream()).collect(Collectors.toList());
}
+ protected List<ToscaPolicy> getNativeArtifactPolicies(@NonNull Map<String, List<ToscaPolicy>> policyTypeGroups) {
+ return policyTypeGroups.entrySet().stream()
+ .filter(entry -> entry.getKey().equals(POLICY_TYPE_DROOLS_NATIVE_RULES.getName()))
+ .flatMap(entry -> entry.getValue().stream()).collect(Collectors.toList());
+ }
+
+ protected List<ToscaPolicy> getNativeControllerPolicies(@NonNull Map<String, List<ToscaPolicy>> policyTypeGroups) {
+ return policyTypeGroups.entrySet().stream()
+ .filter(entry -> entry.getKey().equals(POLICY_TYPE_DROOLS_NATIVE_CONTROLLER.getName()))
+ .flatMap(entry -> entry.getValue().stream()).collect(Collectors.toList());
+ }
+
+ protected String getPolicyIdsMessage(List<ToscaPolicy> policies) {
+ return policies.stream()
+ .distinct()
+ .map(ToscaPolicy::getIdentifier).collect(Collectors.toList())
+ .toString();
+ }
+
/**
* Do I support the mandatory policy types?.
*/
@@ -450,6 +468,10 @@ public class LifecycleFsm implements Startable {
.map(ToscaConceptIdentifier::getName).collect(Collectors.toSet());
}
+ protected List<ToscaPolicy> getActivePolicies() {
+ return new ArrayList<>(policiesMap.values());
+ }
+
/* ** Action Helpers ** */
private boolean startIo() {
diff --git a/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleStatePassive.java b/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleStatePassive.java
index 438dc577..e085e622 100644
--- a/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleStatePassive.java
+++ b/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleStatePassive.java
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* ONAP
* ================================================================================
- * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2019, 2021 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.
@@ -45,7 +45,8 @@ public class LifecycleStatePassive extends LifecycleStateRunning {
protected boolean stateChangeToActive(@NonNull PdpStateChange change) {
fsm.transitionToAction(new LifecycleStateActive(fsm));
fsm.statusAction(response(change.getRequestId(), PdpResponseStatus.SUCCESS, null));
- return fsm.updatePoliciesAction(fsm.resetPoliciesAction());
+ fsm.updatePoliciesAction(fsm.resetPoliciesAction());
+ return true;
}
@Override
diff --git a/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleStateRunning.java b/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleStateRunning.java
index 86540093..77850824 100644
--- a/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleStateRunning.java
+++ b/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleStateRunning.java
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* ONAP
* ================================================================================
- * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2019-2021 AT&T Intellectual Property. All rights reserved.
* Modifications Copyright (C) 2019 Bell Canada.
* Modifications Copyright (C) 2021 Nordix Foundation.
* ================================================================================
@@ -22,9 +22,15 @@
package org.onap.policy.drools.lifecycle;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
+import java.util.Map;
import java.util.function.BiPredicate;
import lombok.NonNull;
+import org.apache.commons.lang3.tuple.Pair;
+import org.onap.policy.common.utils.coder.CoderException;
+import org.onap.policy.drools.domain.models.artifact.NativeArtifactPolicy;
import org.onap.policy.drools.policies.DomainMaker;
import org.onap.policy.models.pdp.concepts.PdpResponseDetails;
import org.onap.policy.models.pdp.concepts.PdpStateChange;
@@ -124,21 +130,57 @@ public abstract class LifecycleStateRunning extends LifecycleStateDefault {
return false;
}
+ // update subgroup if applicable per update message
+
fsm.setSubGroupAction(update.getPdpSubgroup());
- if (!updatePolicies(update.getPolicies())) {
- fsm.statusAction(response(update.getRequestId(), PdpResponseStatus.FAIL, "cannot process policies"));
- return false;
- }
+ // snapshot the active policies previous to apply the new set of active
+ // policies as given by the PAP in the update message
+
+ List<ToscaPolicy> activePoliciesPreUpdate = fsm.getActivePolicies();
+
+ // update policies with the current set of active policies
+
+ Pair<List<ToscaPolicy>, List<ToscaPolicy>> results = updatePoliciesWithResults(update.getPolicies());
+
+ // summary message to return in the update response to the PAP
- return fsm.statusAction(response(update.getRequestId(), PdpResponseStatus.SUCCESS, null));
+ List<ToscaPolicy> failedPolicies = new ArrayList<>(results.getLeft());
+ failedPolicies.addAll(results.getRight());
+
+ // If there are *new* native controller policies deployed, there may
+ // existing native artifact policies (previous to the update event
+ // processing) that would need to be reapplied. This requires
+ // going through the list of those native artifact policies that
+ // were neither deployed or undeployed and re-apply them on top
+ // of the controllers.
+
+ failedPolicies.addAll(reapplyNativeArtifactPolicies(activePoliciesPreUpdate));
+
+ // If there are *new* native artifact policies deployed, there may be existing
+ // non-native policies (previous to the update event processing)
+ // that will need to be reapplied as the new controllers don't know about them.
+ // This requires going through the list of those non-native policies
+ // which neither were undeployed or deployed and re-apply them on top of the
+ // new "brained" controllers.
+
+ failedPolicies.addAll(reapplyNonNativePolicies(activePoliciesPreUpdate));
+
+ return fsm.statusAction(response(update.getRequestId(),
+ (failedPolicies.isEmpty()) ? PdpResponseStatus.SUCCESS : PdpResponseStatus.FAIL,
+ fsm.getPolicyIdsMessage(failedPolicies))) && failedPolicies.isEmpty();
}
}
@Override
public boolean updatePolicies(List<ToscaPolicy> policies) {
+ Pair<List<ToscaPolicy>, List<ToscaPolicy>> results = updatePoliciesWithResults(policies);
+ return results.getLeft().isEmpty() && results.getRight().isEmpty();
+ }
+
+ protected Pair<List<ToscaPolicy>, List<ToscaPolicy>> updatePoliciesWithResults(List<ToscaPolicy> policies) {
if (policies == null) {
- return true;
+ return Pair.of(Collections.emptyList(), Collections.emptyList());
}
// Note that PAP sends the list of all ACTIVE policies with every
@@ -148,40 +190,148 @@ public abstract class LifecycleStateRunning extends LifecycleStateDefault {
// we will deploy those policies that are not installed but
// included in this list.
- boolean success = undeployPolicies(policies);
- return deployPolicies(policies) && success;
+ List<ToscaPolicy> failedUndeployPolicies = undeployPolicies(policies);
+ if (!failedUndeployPolicies.isEmpty()) {
+ logger.warn("update-policies: undeployment failures: {}", fsm.getPolicyIdsMessage(failedUndeployPolicies));
+ failedUndeployPolicies.stream().forEach(fsm::undeployedPolicyAction);
+ }
+
+ List<ToscaPolicy> failedDeployPolicies = deployPolicies(policies);
+ if (!failedDeployPolicies.isEmpty()) {
+ logger.warn("update-policies: deployment failures: {}", fsm.getPolicyIdsMessage(failedDeployPolicies));
+ }
+
+ return Pair.of(failedUndeployPolicies, failedDeployPolicies);
}
- protected boolean deployPolicies(List<ToscaPolicy> policies) {
+ protected List<ToscaPolicy> reapplyNonNativePolicies(List<ToscaPolicy> preActivePolicies) {
+ // only need to re-apply non native policies if there are new native artifact policies
+
+ Map<String, List<ToscaPolicy>> activePoliciesByType = fsm.groupPoliciesByPolicyType(fsm.getActivePolicies());
+ List<ToscaPolicy> activeNativeArtifactPolicies = fsm.getNativeArtifactPolicies(activePoliciesByType);
+
+ Map<String, List<ToscaPolicy>> prePoliciesByType = fsm.groupPoliciesByPolicyType(preActivePolicies);
+ activeNativeArtifactPolicies.removeAll(fsm.getNativeArtifactPolicies(prePoliciesByType));
+ if (activeNativeArtifactPolicies.isEmpty()) {
+ logger.info("reapply-non-native-policies: nothing to reapply, no new native artifact policies");
+ return Collections.emptyList();
+ }
+
+ // need to re-apply non native policies
+
+ // get the non-native policies to be reapplied, this is just the intersection of
+ // the original active set, and the new active set (i.e policies that have not changed,
+ // or in other words, have not been neither deployed or undeployed.
+
+ List<ToscaPolicy> preNonNativePolicies = fsm.getNonNativePolicies(prePoliciesByType);
+ preNonNativePolicies.retainAll(fsm.getNonNativePolicies(activePoliciesByType));
+
+ logger.info("re-applying non-native policies {} because new native artifact policies have been found: {}",
+ fsm.getPolicyIdsMessage(preNonNativePolicies), fsm.getPolicyIdsMessage(activeNativeArtifactPolicies));
+
+ List<ToscaPolicy> failedPolicies = syncPolicies(preNonNativePolicies, this::deployPolicy);
+ logger.info("re-applying non-native policies failures: {}", fsm.getPolicyIdsMessage(failedPolicies));
+
+ return failedPolicies;
+ }
+
+ protected List<ToscaPolicy> reapplyNativeArtifactPolicies(List<ToscaPolicy> preActivePolicies) {
+ // only need to re-apply native artifact policies if there are new native controller policies
+
+ Map<String, List<ToscaPolicy>> activePoliciesByType = fsm.groupPoliciesByPolicyType(fsm.getActivePolicies());
+ List<ToscaPolicy> activeNativeControllerPolicies = fsm.getNativeControllerPolicies(activePoliciesByType);
+
+ Map<String, List<ToscaPolicy>> prePoliciesByType = fsm.groupPoliciesByPolicyType(preActivePolicies);
+ activeNativeControllerPolicies.removeAll(fsm.getNativeControllerPolicies(prePoliciesByType));
+ if (activeNativeControllerPolicies.isEmpty()) {
+ logger.info("reapply-native-artifact-policies: nothing to reapply, no new native controller policies");
+ return Collections.emptyList();
+ }
+
+ // need to re-apply native artifact policies
+
+ // get the native artifact policies to be reapplied, this is just the intersection of
+ // the original active set, and the new active set (i.e policies that have not changed,
+ // or in other words, have not been neither deployed or undeployed.
+
+ List<ToscaPolicy> preNativeArtifactPolicies = fsm.getNativeArtifactPolicies(prePoliciesByType);
+ preNativeArtifactPolicies.retainAll(fsm.getNativeArtifactPolicies(activePoliciesByType));
+
+ logger.info("reapply candidate native artifact policies {} as new native controller policies {} were found",
+ fsm.getPolicyIdsMessage(preNativeArtifactPolicies),
+ fsm.getPolicyIdsMessage(activeNativeControllerPolicies));
+
+ // from the intersection, only need to reapply those for which there is a new native
+ // controller policy
+
+ List<ToscaPolicy> preNativeArtifactPoliciesToApply = new ArrayList<>();
+ for (ToscaPolicy preNativeArtifactPolicy : preNativeArtifactPolicies) {
+ NativeArtifactPolicy nativeArtifactPolicy;
+ try {
+ nativeArtifactPolicy =
+ fsm.getDomainMaker().convertTo(preNativeArtifactPolicy, NativeArtifactPolicy.class);
+ } catch (CoderException | RuntimeException ex) {
+ logger.warn("reapply-native-artifact-policy {}: (unexpected) non conformant: ignoring",
+ preNativeArtifactPolicy.getIdentifier(), ex);
+ continue;
+ }
+
+ String controllerName = nativeArtifactPolicy.getProperties().getController().getName();
+ for (ToscaPolicy policy : activeNativeControllerPolicies) {
+ if (controllerName.equals(policy.getProperties().get("controllerName"))) {
+ preNativeArtifactPoliciesToApply.add(preNativeArtifactPolicy);
+ }
+ }
+ }
+
+ logger.info("reapply set of native artifact policies {} as new native controller policies {} were found",
+ fsm.getPolicyIdsMessage(preNativeArtifactPoliciesToApply),
+ fsm.getPolicyIdsMessage(activeNativeControllerPolicies));
+
+ List<ToscaPolicy> failedPolicies = syncPolicies(preNativeArtifactPoliciesToApply, this::deployPolicy);
+ logger.info("re-applying native artifact policies failures: {}", fsm.getPolicyIdsMessage(failedPolicies));
+
+ // since we want non-native policies to be reapplied when a new native artifact policy has been
+ // reapplied here, remove it from the preActivePolicies, so it is detected as new.
+
+ preActivePolicies.removeAll(preNativeArtifactPoliciesToApply);
+
+ return failedPolicies;
+ }
+
+ protected List<ToscaPolicy> deployPolicies(List<ToscaPolicy> policies) {
return syncPolicies(fsm.getDeployablePoliciesAction(policies), this::deployPolicy);
}
- protected boolean undeployPolicies(List<ToscaPolicy> policies) {
+ protected List<ToscaPolicy> undeployPolicies(List<ToscaPolicy> policies) {
return syncPolicies(fsm.getUndeployablePoliciesAction(policies), this::undeployPolicy);
}
- protected boolean syncPolicies(List<ToscaPolicy> policies,
+ protected List<ToscaPolicy> syncPolicies(List<ToscaPolicy> policies,
BiPredicate<PolicyTypeController, ToscaPolicy> sync) {
- boolean success = true;
+ List<ToscaPolicy> failedPolicies = new ArrayList<>();
DomainMaker domain = fsm.getDomainMaker();
for (ToscaPolicy policy : policies) {
ToscaConceptIdentifier policyType = policy.getTypeIdentifier();
PolicyTypeController controller = fsm.getController(policyType);
if (controller == null) {
logger.warn("no controller found for {}", policyType);
- success = false;
+ failedPolicies.add(policy);
continue;
}
if (domain.isRegistered(policy.getTypeIdentifier())) {
- success = domain.isConformant(policy) && sync.test(controller, policy) && success;
+ if (!domain.isConformant(policy) || !sync.test(controller, policy)) {
+ failedPolicies.add(policy);
+ }
} else {
logger.info("no validator registered for policy type {}", policy.getTypeIdentifier());
- success = sync.test(controller, policy) && success;
+ if (!sync.test(controller, policy)) {
+ failedPolicies.add(policy);
+ }
}
}
-
- return success;
+ return failedPolicies;
}
private void invalidStateChange(PdpStateChange change) {
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 cdf9f147..41d75878 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
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* ONAP
* ================================================================================
- * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2020-2021 AT&T Intellectual Property. All rights reserved.
* Modifications Copyright (C) 2021 Nordix Foundation.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -70,7 +70,18 @@ public class PolicyTypeDroolsController implements PolicyTypeController {
@Override
public boolean deploy(@NonNull ToscaPolicy policy) {
- return perform(policy, (PolicyController controller) -> controller.offer(policy));
+ return perform(policy, controller -> {
+ if (!controller.getDrools().exists(policy)) {
+ return controller.offer(policy);
+ }
+
+ logger.warn("policy {} is not deployed into {} as it already exists",
+ policy.getIdentifier(), controller.getName());
+
+ // provided that the presence of the given policy is the
+ // desired final state of the operation, return success
+ return true;
+ });
}
/**
@@ -93,7 +104,17 @@ public class PolicyTypeDroolsController implements PolicyTypeController {
@Override
public boolean undeploy(@NonNull ToscaPolicy policy) {
- return perform(policy, (PolicyController controller) -> controller.getDrools().delete(policy));
+ return perform(policy, (PolicyController controller) -> {
+ if (controller.getDrools().exists(policy)) {
+ return controller.getDrools().delete(policy);
+ }
+ logger.warn("policy {} is not undeployed from {} as it does not exist",
+ policy.getIdentifier(), controller.getName());
+
+ // provided that the no presence of the policy is the
+ // desired final state of the operation, return success
+ return true;
+ });
}
/**
@@ -134,7 +155,7 @@ public class PolicyTypeDroolsController implements PolicyTypeController {
try {
return operation.test(controller);
} catch (RuntimeException r) {
- logger.warn("invalid offer to controller: {}", controller);
+ logger.warn("invalid operation {} applied to controller: {}", operation, controller);
return false;
}
}
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 b28f06e1..c1b0aab0 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
@@ -1,6 +1,6 @@
/*-
* ============LICENSE_START=======================================================
- * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2019-2021 AT&T Intellectual Property. All rights reserved.
* Modifications Copyright (C) 2021 Nordix Foundation.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -75,7 +75,7 @@ public class RestLifecycleManager {
@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();
+ return Response.status(Response.Status.OK).entity(LifecycleFeature.getFsm().getGroup()).build();
}
/**
@@ -88,8 +88,8 @@ public class RestLifecycleManager {
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();
+ LifecycleFeature.getFsm().setGroup(group);
+ return Response.status(Response.Status.OK).entity(LifecycleFeature.getFsm().getGroup()).build();
}
/**
@@ -101,7 +101,7 @@ public class RestLifecycleManager {
@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();
+ return Response.status(Response.Status.OK).entity(LifecycleFeature.getFsm().getSubgroup()).build();
}
/**
@@ -114,8 +114,8 @@ public class RestLifecycleManager {
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();
+ LifecycleFeature.getFsm().setSubgroup(subgroup);
+ return Response.status(Response.Status.OK).entity(LifecycleFeature.getFsm().getSubgroup()).build();
}
/**
@@ -127,7 +127,7 @@ public class RestLifecycleManager {
@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();
+ return Response.status(Response.Status.OK).entity(LifecycleFeature.getFsm().getProperties()).build();
}
/**
@@ -138,7 +138,7 @@ public class RestLifecycleManager {
@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();
+ return Response.status(Response.Status.OK).entity(LifecycleFeature.getFsm().state()).build();
}
/**
@@ -152,12 +152,12 @@ public class RestLifecycleManager {
@ApiParam(value = "state", required = true) @PathParam("state") String state) {
PdpStateChange change = new PdpStateChange();
- change.setPdpGroup(LifecycleFeature.fsm.getGroup());
- change.setPdpSubgroup(LifecycleFeature.fsm.getSubgroup());
+ change.setPdpGroup(LifecycleFeature.getFsm().getGroup());
+ change.setPdpSubgroup(LifecycleFeature.getFsm().getSubgroup());
change.setState(PdpState.valueOf(state));
- change.setName(LifecycleFeature.fsm.getName());
+ change.setName(LifecycleFeature.getFsm().getName());
- return Response.status(Response.Status.OK).entity(LifecycleFeature.fsm.stateChange(change)).build();
+ return Response.status(Response.Status.OK).entity(LifecycleFeature.getFsm().stateChange(change)).build();
}
/**
@@ -169,7 +169,7 @@ public class RestLifecycleManager {
@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();
+ return Response.status(Response.Status.OK).entity(LifecycleFeature.getFsm().getSource()).build();
}
/**
@@ -181,7 +181,7 @@ public class RestLifecycleManager {
@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();
+ return Response.status(Response.Status.OK).entity(LifecycleFeature.getFsm().getClient()).build();
}
/**
@@ -193,7 +193,7 @@ public class RestLifecycleManager {
@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();
+ return Response.status(Response.Status.OK).entity(LifecycleFeature.getFsm().getStatusTimerSeconds()).build();
}
/**
@@ -206,8 +206,8 @@ public class RestLifecycleManager {
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();
+ LifecycleFeature.getFsm().setStatusTimerSeconds(timeout);
+ return Response.status(Response.Status.OK).entity(LifecycleFeature.getFsm().getStatusTimerSeconds()).build();
}
/**
@@ -220,7 +220,7 @@ public class RestLifecycleManager {
notes = "Lifecycle Policy Types", responseContainer = "List")
public Response policyTypes() {
return Response.status(Response.Status.OK)
- .entity(LifecycleFeature.fsm.getPolicyTypesMap().keySet())
+ .entity(LifecycleFeature.getFsm().getPolicyTypesMap().keySet())
.build();
}
@@ -238,7 +238,7 @@ public class RestLifecycleManager {
@ApiParam(value = "Policy Type Version", required = true)
@PathParam("policyTypeVersion") String policyTypeVersion) {
PolicyTypeController typeController =
- LifecycleFeature.fsm.getPolicyTypesMap()
+ LifecycleFeature.getFsm().getPolicyTypesMap()
.get(new ToscaConceptIdentifier(policyType, policyTypeVersion));
if (typeController == null) {
return Response.status(Response.Status.NOT_FOUND).build();
@@ -258,7 +258,7 @@ public class RestLifecycleManager {
@ApiOperation(value = "List of policies", responseContainer = "List")
public Response policies() {
return Response.status(Response.Status.OK)
- .entity(LifecycleFeature.fsm.getPoliciesMap().keySet())
+ .entity(LifecycleFeature.getFsm().getPoliciesMap().keySet())
.build();
}
@@ -284,10 +284,10 @@ public class RestLifecycleManager {
}
List<ToscaPolicy> policies =
- LifecycleFeature.fsm.getPoliciesMap().values().stream().collect(Collectors.toList());
+ LifecycleFeature.getFsm().getPoliciesMap().values().stream().collect(Collectors.toList());
policies.add(toscaPolicy);
- boolean updateResult = LifecycleFeature.fsm.update(getPolicyUpdate(policies));
+ boolean updateResult = LifecycleFeature.getFsm().update(getPolicyUpdate(policies));
return Response.status((updateResult ? Response.Status.OK : Response.Status.NOT_ACCEPTABLE))
.entity(updateResult)
.build();
@@ -307,7 +307,7 @@ public class RestLifecycleManager {
ToscaPolicy policy;
try {
policy =
- LifecycleFeature.fsm.getPoliciesMap().get(new ToscaConceptIdentifier(policyName, policyVersion));
+ LifecycleFeature.getFsm().getPoliciesMap().get(new ToscaConceptIdentifier(policyName, policyVersion));
} catch (RuntimeException r) {
logger.debug("policy {}:{} has not been found", policyName, policyVersion, r);
return Response.status(Response.Status.NOT_FOUND).build();
@@ -334,7 +334,7 @@ public class RestLifecycleManager {
ToscaPolicy policy;
try {
policy =
- LifecycleFeature.fsm.getPoliciesMap().get(new ToscaConceptIdentifier(policyName, policyVersion));
+ LifecycleFeature.getFsm().getPoliciesMap().get(new ToscaConceptIdentifier(policyName, policyVersion));
} catch (RuntimeException r) {
logger.debug("policy {}:{} has not been found", policyName, policyVersion, r);
return Response.status(Response.Status.NOT_FOUND).build();
@@ -345,10 +345,10 @@ public class RestLifecycleManager {
}
List<ToscaPolicy> policies =
- LifecycleFeature.fsm.getPoliciesMap().values().stream().collect(Collectors.toList());
+ LifecycleFeature.getFsm().getPoliciesMap().values().stream().collect(Collectors.toList());
policies.removeIf(otherPolicy -> policy.getIdentifier().equals(otherPolicy.getIdentifier()));
return Response.status(Response.Status.OK)
- .entity(LifecycleFeature.fsm.update(getPolicyUpdate(policies)))
+ .entity(LifecycleFeature.getFsm().update(getPolicyUpdate(policies)))
.build();
}
@@ -399,7 +399,7 @@ public class RestLifecycleManager {
}
try {
- LifecycleFeature.fsm.getDomainMaker().conformance(toscaPolicy);
+ LifecycleFeature.getFsm().getDomainMaker().conformance(toscaPolicy);
} catch (ValidationFailedException v) {
logger.trace("policy {} validation errors: {}", toscaPolicy, v.getMessage(), v);
return Response.status(Response.Status.NOT_ACCEPTABLE).entity(v.getFailures()).build();
@@ -433,14 +433,14 @@ public class RestLifecycleManager {
}
private PolicyTypeController getPolicyTypeController(ToscaPolicy policy) {
- return LifecycleFeature.fsm.getPolicyTypesMap().get(policy.getTypeIdentifier());
+ return LifecycleFeature.getFsm().getPolicyTypesMap().get(policy.getTypeIdentifier());
}
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.setName(LifecycleFeature.getFsm().getName());
+ update.setPdpGroup(LifecycleFeature.getFsm().getGroup());
+ update.setPdpSubgroup(LifecycleFeature.getFsm().getSubgroup());
update.setPolicies(policies);
return update;
}