From 1e896c1a2d599c02a4494e868cac5fe5399f819f Mon Sep 17 00:00:00 2001 From: Jim Hahn Date: Thu, 24 Oct 2019 11:17:14 -0400 Subject: Add trackers for generating notifications Issue-ID: POLICY-1841 Signed-off-by: Jim Hahn Change-Id: I7d6fe29707685e4711120b6a1e8448f25870a0ef Signed-off-by: Jim Hahn --- .../pap/main/notification/PolicyCommonTracker.java | 202 ++++++++++++++ .../pap/main/notification/PolicyDeployTracker.java | 54 ++++ .../main/notification/PolicyUndeployTracker.java | 53 ++++ .../pap/main/notification/PolicyCommonSupport.java | 94 +++++++ .../main/notification/PolicyCommonTrackerTest.java | 297 +++++++++++++++++++++ .../main/notification/PolicyDeployTrackerTest.java | 120 +++++++++ .../notification/PolicyUndeployTrackerTest.java | 118 ++++++++ 7 files changed, 938 insertions(+) create mode 100644 main/src/main/java/org/onap/policy/pap/main/notification/PolicyCommonTracker.java create mode 100644 main/src/main/java/org/onap/policy/pap/main/notification/PolicyDeployTracker.java create mode 100644 main/src/main/java/org/onap/policy/pap/main/notification/PolicyUndeployTracker.java create mode 100644 main/src/test/java/org/onap/policy/pap/main/notification/PolicyCommonSupport.java create mode 100644 main/src/test/java/org/onap/policy/pap/main/notification/PolicyCommonTrackerTest.java create mode 100644 main/src/test/java/org/onap/policy/pap/main/notification/PolicyDeployTrackerTest.java create mode 100644 main/src/test/java/org/onap/policy/pap/main/notification/PolicyUndeployTrackerTest.java (limited to 'main') diff --git a/main/src/main/java/org/onap/policy/pap/main/notification/PolicyCommonTracker.java b/main/src/main/java/org/onap/policy/pap/main/notification/PolicyCommonTracker.java new file mode 100644 index 00000000..0404e1fe --- /dev/null +++ b/main/src/main/java/org/onap/policy/pap/main/notification/PolicyCommonTracker.java @@ -0,0 +1,202 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP PAP + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.pap.main.notification; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.function.BiPredicate; +import org.onap.policy.models.pap.concepts.PolicyStatus; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifier; + +/** + * Common super class for deploy and undeploy trackers. + */ +public abstract class PolicyCommonTracker { + + /** + * Maps a policy id to its deployment data. The subclass determines when an entry is + * removed. + * + *

+ * Use a LinkedHashMap, because we'll be doing lots of iteration over the map, and + * iteration over a LinkedHashMap is faster than over a plain HashMap. + */ + private final Map policy2data = new LinkedHashMap<>(); + + + /** + * Constructs the object. + */ + public PolicyCommonTracker() { + super(); + } + + /** + * Adds data to the tracker. + * + * @param data data to be added to the tracker + */ + public void addData(PolicyPdpNotificationData data) { + policy2data.computeIfAbsent(data.getPolicyId(), policyId -> new PolicyTrackerData(data.getPolicyType())) + .addPdps(data.getPdps()); + } + + /** + * Removes a set of PDPs from all policies within the tracker. + * + * @param notifyData data identifying the policy and the PDPs to be removed from it + * @param statusList status messages are added here if policies become complete as a + * result of this operation + */ + public void removeData(PolicyPdpNotificationData notifyData, List statusList) { + + policy2data.computeIfPresent(notifyData.getPolicyId(), (policyId, data) -> { + + if (!data.removePdps(notifyData.getPdps())) { + // not complete yet + return data; + } + + // this policy is complete - notify + statusList.add(makeStatus(policyId, data)); + + return (shouldRemove(data) ? null : data); + }); + } + + /** + * Removes a PDP from all policies within the tracker. + * + * @param pdp PDP to be removed + * @param statusList status messages are added here if policies become complete as a + * result of this operation + */ + public void removePdp(String pdp, List statusList) { + updateMap(statusList, (policyId, data) -> data.removePdp(pdp)); + } + + /** + * Processes a response from a PDP. + * + * @param pdp PDP of interest + * @param activePolicies policies that are still active on the PDP, as specified in + * the response + * @param statusList status messages are added here if policies become complete as a + * result of this operation + */ + public void processResponse(String pdp, Collection activePolicies, + List statusList) { + processResponse(pdp, new HashSet<>(activePolicies), statusList); + } + + /** + * Processes a response from a PDP. + * + * @param pdp PDP of interest + * @param activePolicies policies that are still active on the PDP, as specified in + * the response + * @param statusList status messages are added here if policies become complete as a + * result of this operation + */ + public void processResponse(String pdp, Set activePolicies, List statusList) { + updateMap(statusList, (policyId, data) -> updateData(pdp, data, activePolicies.contains(policyId))); + } + + /** + * Updates the map. + * + *

+ * Note: this iterates through the whole map. While it may be more efficient to + * iterate through just the policies relevant to the PDP, that would complicate the + * code and complicate the testing. In addition, this should still perform well + * enough, but if not, it can always be enhanced. + * + * @param statusList status messages are added here if policies become complete as a + * result of this operation + * @param updater function to update a policy's data. Returns {@code true} if the + * policy is complete (i.e., no longer awaiting any responses) + */ + private void updateMap(List statusList, + BiPredicate updater) { + + Iterator> iter = policy2data.entrySet().iterator(); + while (iter.hasNext()) { + Entry ent = iter.next(); + + ToscaPolicyIdentifier policyId = ent.getKey(); + PolicyTrackerData data = ent.getValue(); + + if (!updater.test(policyId, data)) { + // not complete yet + continue; + } + + // this policy is complete - notify + statusList.add(makeStatus(policyId, data)); + + if (shouldRemove(data)) { + iter.remove(); + } + } + } + + /** + * Updates the policy data, based on a response from a PDP. + * + * @param pdp PDP whose response was just received + * @param data data associated with the policy of interest + * @param stillActive {@code true} if the policy is still active for the PDP, + * {@code false} otherwise + * @return {@code true} if the policy is complete (i.e., no longer awaiting any + * responses), {@code false} otherwise + */ + protected abstract boolean updateData(String pdp, PolicyTrackerData data, boolean stillActive); + + /** + * Determines if a policy should be removed from the tracker, based on the state of + * its data. + * + * @param data data associated with the policy of interest + * @return {@code true} if the policy should be removed from the tracker, + * {@code false} otherwise + */ + protected abstract boolean shouldRemove(PolicyTrackerData data); + + /** + * Makes a status notification for the given policy. + * + * @param policyId policy ID + * @param data data to be used to set the status fields + * @return a new status notification + */ + private synchronized PolicyStatus makeStatus(ToscaPolicyIdentifier policyId, PolicyTrackerData data) { + + PolicyStatus status = new PolicyStatus(data.getPolicyType(), policyId); + data.putValuesInto(status); + return status; + } +} diff --git a/main/src/main/java/org/onap/policy/pap/main/notification/PolicyDeployTracker.java b/main/src/main/java/org/onap/policy/pap/main/notification/PolicyDeployTracker.java new file mode 100644 index 00000000..17a5e211 --- /dev/null +++ b/main/src/main/java/org/onap/policy/pap/main/notification/PolicyDeployTracker.java @@ -0,0 +1,54 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP PAP + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.pap.main.notification; + +/** + * Tracker for policy deployments to PDPs. + * + *

+ * Policies are not removed from the internal map until all of the sets contained within + * the data are empty. This may be the result of a PDP being removed from the system + * because it is no longer responsive, or because the PDP Subgroup that contained it is + * deleted. + */ +public class PolicyDeployTracker extends PolicyCommonTracker { + + /** + * Constructs the object. + */ + public PolicyDeployTracker() { + super(); + } + + @Override + protected boolean updateData(String pdp, PolicyTrackerData data, boolean stillActive) { + return (stillActive ? data.success(pdp) : data.fail(pdp)); + } + + /** + * Returns {@code true} only when the data is completely empty (i.e., it has no + * more PDPs) + */ + @Override + protected boolean shouldRemove(PolicyTrackerData data) { + return data.isEmpty(); + } +} diff --git a/main/src/main/java/org/onap/policy/pap/main/notification/PolicyUndeployTracker.java b/main/src/main/java/org/onap/policy/pap/main/notification/PolicyUndeployTracker.java new file mode 100644 index 00000000..964ff44d --- /dev/null +++ b/main/src/main/java/org/onap/policy/pap/main/notification/PolicyUndeployTracker.java @@ -0,0 +1,53 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP PAP + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.pap.main.notification; + +/** + * Tracker for policy undeployments from PDPs. + * + *

+ * Policies are removed from the internal map when they are no longer waiting for + * responses from any PDPs. + */ +public class PolicyUndeployTracker extends PolicyCommonTracker { + + /** + * Constructs the object. + */ + public PolicyUndeployTracker() { + super(); + } + + @Override + protected boolean updateData(String pdp, PolicyTrackerData data, boolean stillActive) { + // note: still active means the policy wasn't undeployed, thus it's a failure + return (stillActive ? data.fail(pdp) : data.success(pdp)); + } + + /** + * Returns {@code true} only when the data is "complete" (i.e., not awaiting responses + * from any other PDPs). + */ + @Override + protected boolean shouldRemove(PolicyTrackerData data) { + return data.isComplete(); + } +} diff --git a/main/src/test/java/org/onap/policy/pap/main/notification/PolicyCommonSupport.java b/main/src/test/java/org/onap/policy/pap/main/notification/PolicyCommonSupport.java new file mode 100644 index 00000000..14f3055c --- /dev/null +++ b/main/src/test/java/org/onap/policy/pap/main/notification/PolicyCommonSupport.java @@ -0,0 +1,94 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP PAP + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.pap.main.notification; + +import java.util.Arrays; +import java.util.List; +import org.junit.Before; +import org.onap.policy.models.pap.concepts.PolicyStatus; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier; + +/** + * Super class for policy notification test classes. + */ +public class PolicyCommonSupport { + protected static final String MAP_FIELD = "policy2data"; + protected static final String PDP1 = "pdp-1"; + protected static final String PDP2 = "pdp-2"; + protected static final String PDP3 = "pdp-3"; + protected static final String PDP4 = "pdp-4"; + + protected ToscaPolicyTypeIdentifier type; + protected ToscaPolicyIdentifier policy1; + protected ToscaPolicyIdentifier policy2; + protected ToscaPolicyIdentifier policy3; + protected ToscaPolicyIdentifier policy4; + + /** + * Creates various objects. + */ + @Before + public void setUp() { + type = new ToscaPolicyTypeIdentifier("my-type", "3.2.1"); + policy1 = new ToscaPolicyIdentifier("my-id-a", "1.2.0"); + policy2 = new ToscaPolicyIdentifier("my-id-b", "1.2.1"); + policy3 = new ToscaPolicyIdentifier("my-id-c", "1.2.2"); + policy4 = new ToscaPolicyIdentifier("my-id-d", "1.2.3"); + } + + /** + * Makes notification data. + * + * @param policyId ID of the policy with which the data should be associated + * @param pdps PDPs to be included within the data + * @return a new notification data structure + */ + protected PolicyPdpNotificationData makeData(ToscaPolicyIdentifier policyId, String... pdps) { + PolicyPdpNotificationData data = new PolicyPdpNotificationData(policyId, type); + data.addAll(Arrays.asList(pdps)); + return data; + } + + /** + * Extracts the counts from the sets contained within tracker data. + * + * @param data data from which to extract the sets + * @return a list containing the number of successes, failures, and incomplete PDPs, + * in that order + */ + protected List getCounts(PolicyTrackerData data) { + PolicyStatus status = new PolicyStatus(); + data.putValuesInto(status); + return getCounts(status); + } + + /** + * Extracts the counts from within a status notification. + * + * @param status status from which to extract the counts + * @return a list containing the number of successes, failures, and incomplete PDPs, + * in that order + */ + protected List getCounts(PolicyStatus status) { + return Arrays.asList(status.getSuccessCount(), status.getFailureCount(), status.getIncompleteCount()); + } +} diff --git a/main/src/test/java/org/onap/policy/pap/main/notification/PolicyCommonTrackerTest.java b/main/src/test/java/org/onap/policy/pap/main/notification/PolicyCommonTrackerTest.java new file mode 100644 index 00000000..cfcf4471 --- /dev/null +++ b/main/src/test/java/org/onap/policy/pap/main/notification/PolicyCommonTrackerTest.java @@ -0,0 +1,297 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP PAP + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.pap.main.notification; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import org.junit.Before; +import org.junit.Test; +import org.onap.policy.models.pap.concepts.PolicyStatus; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifier; +import org.powermock.reflect.Whitebox; + +public class PolicyCommonTrackerTest extends PolicyCommonSupport { + + private MyTracker tracker; + private Map map; + + /** + * Creates various objects, including {@link #tracker}. + */ + @Before + public void setUp() { + super.setUp(); + + tracker = new MyTracker(); + } + + @Test + public void testAddData() { + tracker.addData(makeData(policy1, PDP1, PDP2)); + assertEquals(1, map.size()); + + PolicyTrackerData data = map.get(policy1); + assertNotNull(data); + assertFalse(data.isComplete()); + + // add same policy - should still have the same data object + tracker.addData(makeData(policy1, PDP1, PDP3)); + assertEquals(1, map.size()); + assertSame(data, map.get(policy1)); + assertFalse(data.isComplete()); + + // add another policy + tracker.addData(makeData(policy2, PDP2)); + assertEquals(2, map.size()); + + // data for policy 1 is unchanged + assertSame(data, map.get(policy1)); + assertFalse(data.isComplete()); + + // policy 2 should have its own data + assertTrue(map.get(policy2) != data); + data = map.get(policy2); + assertNotNull(data); + assertFalse(data.isComplete()); + } + + /** + * Tests removeData() when the policy isn't in the map. + */ + @Test + public void testRemoveDataUnknownPolicy() { + tracker.addData(makeData(policy1, PDP1, PDP2)); + tracker.addData(makeData(policy2, PDP1, PDP3)); + + // remove a policy that isn't in the map + List statusList = new ArrayList<>(); + tracker.removeData(makeData(policy3, PDP1), statusList); + assertTrue(statusList.isEmpty()); + assertEquals(2, map.size()); + } + + /** + * Tests removeData() when only some PDPs are removed from the policy. + */ + @Test + public void testRemoveDataRemoveSomePdps() { + tracker.addData(makeData(policy1, PDP1, PDP2)); + tracker.addData(makeData(policy2, PDP1, PDP3)); + + // remove some PDPs from a policy - no notifications and no changes to the map + List statusList = new ArrayList<>(); + tracker.removeData(makeData(policy2, PDP1), statusList); + assertTrue(statusList.isEmpty()); + assertTrue(map.containsKey(policy1)); + assertTrue(map.containsKey(policy2)); + } + + /** + * Tests removeData() when the subclass indicates that the policy should NOT be removed. + */ + @Test + public void testRemoveDataDoNotRemovePolicy() { + tracker = new MyTracker() { + @Override + protected boolean shouldRemove(PolicyTrackerData data) { + return false; + } + }; + + tracker.addData(makeData(policy1, PDP1, PDP2)); + tracker.addData(makeData(policy2, PDP1, PDP3)); + + // remove all the PDPs from one policy, but do NOT remove the policy + List statusList = new ArrayList<>(); + tracker.removeData(makeData(policy2, PDP1, PDP3), statusList); + assertEquals(1, statusList.size()); + assertEquals(policy2, statusList.get(0).getPolicy()); + assertTrue(map.containsKey(policy1)); + assertTrue(map.containsKey(policy2)); + } + + /** + * Tests removeData() when the subclass indicates that the policy should be removed. + */ + @Test + public void testRemoveDataRemovePolicy() { + tracker.addData(makeData(policy1, PDP1, PDP2)); + tracker.addData(makeData(policy2, PDP1, PDP3)); + + // remove all the PDPs from one policy, and remove the policy + List statusList = new ArrayList<>(); + tracker.removeData(makeData(policy1, PDP1, PDP2, PDP3), statusList); + assertEquals(1, statusList.size()); + assertEquals(policy1, statusList.get(0).getPolicy()); + assertFalse(map.containsKey(policy1)); + assertTrue(map.containsKey(policy2)); + } + + @Test + public void testRemovePdp() { + tracker.addData(makeData(policy1, PDP1)); + tracker.addData(makeData(policy2, PDP1, PDP3)); + tracker.addData(makeData(policy3, PDP1, PDP2, PDP3)); + tracker.addData(makeData(policy4, PDP4, PDP2, PDP3)); + + List statusList = new ArrayList<>(); + tracker.removePdp(PDP1, statusList); + + assertEquals(1, statusList.size()); + assertEquals(policy1, statusList.get(0).getPolicy()); + + assertEquals(3, map.size()); + assertFalse(map.containsKey(policy1)); + assertEquals("[0, 0, 1]", getCounts(map.get(policy2)).toString()); + assertEquals("[0, 0, 2]", getCounts(map.get(policy3)).toString()); + assertEquals("[0, 0, 3]", getCounts(map.get(policy4)).toString()); + } + + @Test + public void testProcessResponse() { + tracker.addData(makeData(policy1, PDP1)); + tracker.addData(makeData(policy2, PDP1, PDP3)); + tracker.addData(makeData(policy3, PDP1, PDP2, PDP3)); + tracker.addData(makeData(policy4, PDP4, PDP2, PDP3)); + + List statusList = new ArrayList<>(); + tracker.processResponse(PDP1, Arrays.asList(policy3), statusList); + + assertEquals(1, statusList.size()); + assertEquals(policy1, statusList.get(0).getPolicy()); + + assertEquals(3, map.size()); + assertFalse(map.containsKey(policy1)); + assertEquals("[0, 1, 1]", getCounts(map.get(policy2)).toString()); + assertEquals("[1, 0, 2]", getCounts(map.get(policy3)).toString()); + assertEquals("[0, 0, 3]", getCounts(map.get(policy4)).toString()); + } + + @Test + public void testUpdateMap() { + tracker.addData(makeData(policy1, PDP1)); + tracker.addData(makeData(policy2, PDP1, PDP3)); + tracker.addData(makeData(policy3, PDP1, PDP2, PDP3)); + tracker.addData(makeData(policy4, PDP4, PDP2, PDP3)); + + List statusList = new ArrayList<>(); + tracker.processResponse(PDP1, Arrays.asList(policy3), statusList); + + assertEquals(1, statusList.size()); + assertEquals(policy1, statusList.get(0).getPolicy()); + + assertEquals(3, map.size()); + assertFalse(map.containsKey(policy1)); + assertEquals("[0, 1, 1]", getCounts(map.get(policy2)).toString()); + assertEquals("[1, 0, 2]", getCounts(map.get(policy3)).toString()); + assertEquals("[0, 0, 3]", getCounts(map.get(policy4)).toString()); + } + + /** + * Tests updateMap() when the policy should NOT be removed. + */ + @Test + public void testUpdateMapDoNotRemove() { + tracker = new MyTracker() { + @Override + protected boolean shouldRemove(PolicyTrackerData data) { + return false; + } + }; + + tracker.addData(makeData(policy1, PDP1, PDP2)); + + // indicate that PDP2 has succeeded + tracker.processResponse(PDP2, Arrays.asList(policy1), new ArrayList<>(0)); + + // indicate that PDP1 has succeeded + List statusList = new ArrayList<>(); + tracker.processResponse(PDP1, Arrays.asList(policy1), statusList); + + assertEquals(1, statusList.size()); + assertEquals(policy1, statusList.get(0).getPolicy()); + + assertEquals(1, map.size()); + assertTrue(map.containsKey(policy1)); + assertEquals("[2, 0, 0]", getCounts(map.get(policy1)).toString()); + } + + /** + * Tests updateMap() when the policy SHOULD be removed. + */ + @Test + public void testUpdateMapRemovePolicy() { + tracker.addData(makeData(policy1, PDP1, PDP2)); + + // indicate that PDP2 has succeeded + tracker.processResponse(PDP2, Arrays.asList(policy1), new ArrayList<>(0)); + + // indicate that PDP1 has succeeded + List statusList = new ArrayList<>(); + tracker.processResponse(PDP1, Arrays.asList(policy1), statusList); + + assertEquals(1, statusList.size()); + assertEquals(policy1, statusList.get(0).getPolicy()); + assertEquals("[2, 0, 0]", getCounts(statusList.get(0)).toString()); + + assertTrue(map.isEmpty()); + } + + @Test + public void testMakeStatus() { + tracker.addData(makeData(policy1, PDP1, PDP2)); + + // indicate that PDP2 has succeeded + List statusList = new ArrayList<>(); + tracker.processResponse(PDP2, Arrays.asList(policy1), statusList); + assertTrue(statusList.isEmpty()); + + // indicate that PDP1 has failed + tracker.processResponse(PDP1, Arrays.asList(policy2), statusList); + assertEquals(1, statusList.size()); + assertEquals("[1, 1, 0]", getCounts(statusList.get(0)).toString()); + } + + private class MyTracker extends PolicyCommonTracker { + + public MyTracker() { + map = Whitebox.getInternalState(this, MAP_FIELD); + } + + @Override + protected boolean updateData(String pdp, PolicyTrackerData data, boolean stillActive) { + return (stillActive ? data.success(pdp) : data.fail(pdp)); + } + + @Override + protected boolean shouldRemove(PolicyTrackerData data) { + return data.isComplete(); + } + } +} diff --git a/main/src/test/java/org/onap/policy/pap/main/notification/PolicyDeployTrackerTest.java b/main/src/test/java/org/onap/policy/pap/main/notification/PolicyDeployTrackerTest.java new file mode 100644 index 00000000..bd093141 --- /dev/null +++ b/main/src/test/java/org/onap/policy/pap/main/notification/PolicyDeployTrackerTest.java @@ -0,0 +1,120 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP PAP + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.pap.main.notification; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.onap.policy.models.pap.concepts.PolicyStatus; + +public class PolicyDeployTrackerTest extends PolicyCommonSupport { + + @Mock + private PolicyTrackerData data; + + private PolicyDeployTracker tracker; + + /** + * Creates various objects, including {@link #tracker}. + */ + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + super.setUp(); + + tracker = new PolicyDeployTracker(); + } + + @Test + public void test() { + tracker.addData(makeData(policy1, PDP1, PDP2)); + + // indicate that PDP2 has succeeded + tracker.processResponse(PDP2, Arrays.asList(policy1), new ArrayList<>(0)); + + // indicate that PDP1 has succeeded + List statusList = new ArrayList<>(); + tracker.processResponse(PDP1, Arrays.asList(policy1), statusList); + + assertEquals(1, statusList.size()); + assertEquals(policy1, statusList.get(0).getPolicy()); + assertEquals("[2, 0, 0]", getCounts(statusList.get(0)).toString()); + + // indicate that PDP1 has failed - should get a notification, if still in the map + statusList.clear(); + tracker.processResponse(PDP1, Collections.emptyList(), statusList); + assertEquals(1, statusList.size()); + assertEquals(policy1, statusList.get(0).getPolicy()); + assertEquals("[1, 1, 0]", getCounts(statusList.get(0)).toString()); + } + + @Test + public void testUpdateData() { + // when success returns false + assertFalse(tracker.updateData(PDP1, data, true)); + verify(data).success(PDP1); + verify(data, never()).fail(any()); + + // when inactive + assertFalse(tracker.updateData(PDP1, data, false)); + verify(data).success(PDP1); + verify(data).fail(any()); + + // when success & fail return true + when(data.success(PDP1)).thenReturn(true); + when(data.fail(PDP1)).thenReturn(true); + assertTrue(tracker.updateData(PDP1, data, true)); + verify(data, times(2)).success(PDP1); + verify(data, times(1)).fail(PDP1); + + // when inactive + assertTrue(tracker.updateData(PDP1, data, false)); + verify(data, times(2)).success(PDP1); + verify(data, times(2)).fail(PDP1); + } + + @Test + public void testShouldRemove() { + // when data is complete, but not empty + when(data.isComplete()).thenReturn(true); + when(data.isEmpty()).thenReturn(false); + assertFalse(tracker.shouldRemove(data)); + + // when data is empty + when(data.isEmpty()).thenReturn(true); + assertTrue(tracker.shouldRemove(data)); + } +} diff --git a/main/src/test/java/org/onap/policy/pap/main/notification/PolicyUndeployTrackerTest.java b/main/src/test/java/org/onap/policy/pap/main/notification/PolicyUndeployTrackerTest.java new file mode 100644 index 00000000..d837cbad --- /dev/null +++ b/main/src/test/java/org/onap/policy/pap/main/notification/PolicyUndeployTrackerTest.java @@ -0,0 +1,118 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP PAP + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.pap.main.notification; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.onap.policy.models.pap.concepts.PolicyStatus; + +public class PolicyUndeployTrackerTest extends PolicyCommonSupport { + + @Mock + private PolicyTrackerData data; + + private PolicyUndeployTracker tracker; + + /** + * Creates various objects, including {@link #tracker}. + */ + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + super.setUp(); + + tracker = new PolicyUndeployTracker(); + } + + @Test + public void test() { + tracker.addData(makeData(policy1, PDP1, PDP2)); + + // indicate that PDP2 has been undeployed + tracker.processResponse(PDP2, Collections.emptyList(), new ArrayList<>(0)); + + // indicate that PDP1 has been undeployed + List statusList = new ArrayList<>(); + tracker.processResponse(PDP1, Collections.emptyList(), statusList); + + assertEquals(1, statusList.size()); + assertEquals(policy1, statusList.get(0).getPolicy()); + assertEquals("[2, 0, 0]", getCounts(statusList.get(0)).toString()); + + // indicate that PDP1 has been re-deployed - should not get a notification, + // because policy + // is gone + statusList.clear(); + tracker.processResponse(PDP1, Arrays.asList(policy1), statusList); + assertTrue(statusList.isEmpty()); + } + + @Test + public void testUpdateData() { + // when success returns false + assertFalse(tracker.updateData(PDP1, data, false)); + verify(data).success(PDP1); + verify(data, never()).fail(any()); + + // when inactive + assertFalse(tracker.updateData(PDP1, data, true)); + verify(data).success(PDP1); + verify(data).fail(any()); + + // when success & fail return true + when(data.success(PDP1)).thenReturn(true); + when(data.fail(PDP1)).thenReturn(true); + assertTrue(tracker.updateData(PDP1, data, false)); + verify(data, times(2)).success(PDP1); + verify(data, times(1)).fail(PDP1); + + // when inactive + assertTrue(tracker.updateData(PDP1, data, true)); + verify(data, times(2)).success(PDP1); + verify(data, times(2)).fail(PDP1); + } + + @Test + public void testShouldRemove() { + // when data is not complete + assertFalse(tracker.shouldRemove(data)); + + // when data is complete + when(data.isComplete()).thenReturn(true); + assertTrue(tracker.shouldRemove(data)); + } +} -- cgit 1.2.3-korg