2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.onap.policy.pap.main.rest.depundep;
23 import static org.assertj.core.api.Assertions.assertThatThrownBy;
24 import static org.junit.Assert.assertEquals;
25 import static org.junit.Assert.assertSame;
26 import static org.junit.Assert.assertTrue;
27 import static org.mockito.Matchers.any;
28 import static org.mockito.Mockito.never;
29 import static org.mockito.Mockito.times;
30 import static org.mockito.Mockito.verify;
31 import static org.mockito.Mockito.when;
33 import java.util.Arrays;
34 import java.util.Collections;
35 import java.util.LinkedList;
36 import java.util.List;
37 import java.util.Queue;
38 import java.util.TreeSet;
39 import javax.ws.rs.core.Response.Status;
40 import org.junit.AfterClass;
41 import org.junit.Before;
42 import org.junit.Test;
43 import org.mockito.ArgumentCaptor;
44 import org.onap.policy.common.utils.services.Registry;
45 import org.onap.policy.models.base.PfModelException;
46 import org.onap.policy.models.base.PfModelRuntimeException;
47 import org.onap.policy.models.pap.concepts.PdpDeployPolicies;
48 import org.onap.policy.models.pdp.concepts.PdpGroup;
49 import org.onap.policy.models.pdp.concepts.PdpUpdate;
50 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
51 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifier;
52 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifierOptVersion;
53 import org.onap.policy.pap.main.notification.PolicyPdpNotificationData;
54 import org.powermock.reflect.Whitebox;
56 public class TestProviderBase extends ProviderSuper {
57 private static final String EXPECTED_EXCEPTION = "expected exception";
59 private static final String POLICY1_NAME = "policyA";
60 private static final String POLICY1_VERSION = "1.2.3";
61 private static final String GROUP1_NAME = "groupA";
62 private static final String GROUP2_NAME = "groupB";
63 private static final String PDP1_TYPE = "pdpTypeA";
64 private static final String PDP2_TYPE = "pdpTypeB";
65 private static final String PDP3_TYPE = "pdpTypeC";
66 private static final String PDP4_TYPE = "pdpTypeD";
67 private static final String PDP1 = "pdpA";
68 private static final String PDP2 = "pdpB";
69 private static final String PDP3 = "pdpC";
70 private static final String PDP4 = "pdpD";
72 private MyProvider prov;
76 public static void tearDownAfterClass() {
77 Registry.newRegistry();
81 * Configures mocks and objects.
83 * @throws Exception if an error occurs
86 public void setUp() throws Exception {
90 when(dao.getFilteredPolicyList(any())).thenReturn(loadPolicies("daoPolicyList.json"));
92 prov = new MyProvider();
96 public void testProviderBase() {
97 assertSame(lockit, Whitebox.getInternalState(prov, "updateLock"));
98 assertSame(reqmap, Whitebox.getInternalState(prov, "requestMap"));
99 assertSame(daofact, Whitebox.getInternalState(prov, "daoFactory"));
103 public void testProcess() throws Exception {
104 prov.process(loadRequest(), this::handle);
106 assertGroup(getGroupUpdates(), GROUP1_NAME);
108 assertUpdate(getUpdateRequests(1), GROUP1_NAME, PDP1_TYPE, PDP1);
110 ArgumentCaptor<PolicyPdpNotificationData> captor = ArgumentCaptor.forClass(PolicyPdpNotificationData.class);
111 verify(notifier, times(2)).addDeploymentData(captor.capture());
112 assertNotifier(captor, PDP1, PDP3);
114 captor = ArgumentCaptor.forClass(PolicyPdpNotificationData.class);
115 verify(notifier, times(2)).addUndeploymentData(captor.capture());
116 assertNotifier(captor, PDP2, PDP4);
119 private void assertNotifier(ArgumentCaptor<PolicyPdpNotificationData> captor, String firstPdp, String secondPdp) {
120 assertEquals(1, captor.getAllValues().get(0).getPdps().size());
121 assertEquals(1, captor.getAllValues().get(1).getPdps().size());
123 // ensure the order by using a TreeSet
124 TreeSet<String> pdps = new TreeSet<>(captor.getAllValues().get(0).getPdps());
125 pdps.addAll(captor.getAllValues().get(1).getPdps());
126 assertEquals("[" + firstPdp + ", " + secondPdp + "]", pdps.toString());
130 public void testProcess_CreateEx() throws Exception {
131 PfModelException ex = new PfModelException(Status.BAD_REQUEST, EXPECTED_EXCEPTION);
132 when(daofact.create()).thenThrow(ex);
134 assertThatThrownBy(() -> prov.process(loadEmptyRequest(), this::handle)).isSameAs(ex);
138 public void testProcess_PfRtEx() throws Exception {
139 PfModelRuntimeException ex = new PfModelRuntimeException(Status.BAD_REQUEST, EXPECTED_EXCEPTION);
140 when(daofact.create()).thenThrow(ex);
142 assertThatThrownBy(() -> prov.process(loadEmptyRequest(), this::handle)).isSameAs(ex);
146 public void testProcess_RuntimeEx() throws Exception {
147 RuntimeException ex = new RuntimeException(EXPECTED_EXCEPTION);
148 when(daofact.create()).thenThrow(ex);
150 assertThatThrownBy(() -> prov.process(loadEmptyRequest(), this::handle)).isInstanceOf(PfModelException.class)
151 .hasMessage("request failed").hasCause(ex);
155 public void testProcessPolicy_NoGroups() throws Exception {
156 when(dao.getFilteredPdpGroups(any())).thenReturn(Collections.emptyList());
158 SessionData session = new SessionData(dao);
159 ToscaPolicyIdentifierOptVersion ident = new ToscaPolicyIdentifierOptVersion(POLICY1_NAME, POLICY1_VERSION);
160 assertThatThrownBy(() -> prov.processPolicy(session, ident)).isInstanceOf(PfModelException.class)
161 .hasMessage("policy not supported by any PDP group: policyA 1.2.3");
166 public void testGetPolicy() throws Exception {
167 PfModelException exc = new PfModelException(Status.CONFLICT, EXPECTED_EXCEPTION);
168 when(dao.getFilteredPolicyList(any())).thenThrow(exc);
170 assertThatThrownBy(() -> prov.process(loadRequest(), this::handle)).isInstanceOf(PfModelRuntimeException.class)
175 public void testGetPolicy_NotFound() throws Exception {
176 when(dao.getFilteredPolicyList(any())).thenReturn(Collections.emptyList());
178 assertThatThrownBy(() -> prov.process(loadRequest(), this::handle)).isInstanceOf(PfModelRuntimeException.class)
179 .hasMessage("cannot find policy: policyA 1.2.3")
180 .extracting(ex -> ((PfModelRuntimeException) ex).getErrorResponse().getResponseCode())
181 .isEqualTo(Status.NOT_FOUND);
185 public void testGetGroup() throws Exception {
186 when(dao.getFilteredPdpGroups(any())).thenReturn(loadGroups("getGroupDao.json"))
187 .thenReturn(loadGroups("groups.json"));
189 prov.process(loadRequest(), this::handle);
191 assertGroup(getGroupUpdates(), GROUP1_NAME);
195 public void testUpgradeGroup() throws Exception {
197 * Each subgroup has a different PDP type and name.
199 * Type is not supported by the first subgroup.
201 * Second subgroup matches.
203 * Third subgroup already contains the policy.
205 * Last subgroup matches.
208 when(dao.getFilteredPdpGroups(any())).thenReturn(loadGroups("upgradeGroupDao.json"));
211 prov.add(false, true, false, true);
213 prov.process(loadRequest(), this::handle);
215 assertGroup(getGroupUpdates(), GROUP1_NAME);
217 List<PdpUpdate> requests = getUpdateRequests(2);
218 assertUpdate(requests, GROUP1_NAME, PDP2_TYPE, PDP2);
219 assertUpdate(requests, GROUP1_NAME, PDP4_TYPE, PDP4);
223 public void testUpgradeGroup_Multiple() throws Exception {
225 * Policy data in the DB: policy1=type1, policy2=type2, policy3=type3,
228 * Group data in the DB: group1=(type1=pdp1, type3=pdp3) group2=(type2=pdp2)
230 * Request specifies: policy1, policy2, policy3, policy4
232 * Should create new versions of group1 and group2.
234 * Should update old versions of group1 and group2. Should also update new version
237 * Should generate updates to pdp1, pdp2, and pdp3.
240 when(dao.getFilteredPolicyList(any())).thenReturn(loadPolicies("daoPolicyList.json"))
241 .thenReturn(loadPolicies("upgradeGroupPolicy2.json"))
242 .thenReturn(loadPolicies("upgradeGroupPolicy3.json"))
243 .thenReturn(loadPolicies("upgradeGroupPolicy4.json"));
245 List<PdpGroup> groups1 = loadGroups("upgradeGroupGroup1.json");
246 List<PdpGroup> groups2 = loadGroups("upgradeGroupGroup2.json");
249 * these are in pairs of (get-group, get-max-group) matching each policy in the
253 when(dao.getFilteredPdpGroups(any()))
254 .thenReturn(groups1).thenReturn(groups1)
255 .thenReturn(groups2).thenReturn(groups2)
256 .thenReturn(groups1).thenReturn(groups1)
257 .thenReturn(groups1).thenReturn(groups1);
260 // multiple policies in the request
261 PdpDeployPolicies request = loadFile("updateGroupReqMultiple.json", PdpDeployPolicies.class);
263 prov.process(request, (data, deploy) -> {
264 for (ToscaPolicyIdentifierOptVersion policy : deploy.getPolicies()) {
265 handle(data, policy);
270 List<PdpGroup> changes = getGroupUpdates();
271 assertGroup(changes, GROUP1_NAME);
272 assertGroup(changes, GROUP2_NAME);
274 List<PdpUpdate> requests = getUpdateRequests(3);
275 assertUpdateIgnorePolicy(requests, GROUP1_NAME, PDP1_TYPE, PDP1);
276 assertUpdateIgnorePolicy(requests, GROUP2_NAME, PDP2_TYPE, PDP2);
277 assertUpdateIgnorePolicy(requests, GROUP1_NAME, PDP3_TYPE, PDP3);
281 public void testUpgradeGroup_NothingUpdated() throws Exception {
285 prov.process(loadRequest(), this::handle);
287 verify(dao, never()).createPdpGroups(any());
288 verify(dao, never()).updatePdpGroups(any());
289 verify(reqmap, never()).addRequest(any(PdpUpdate.class));
293 protected void assertUpdate(List<PdpUpdate> updates, String groupName, String pdpType, String pdpName) {
295 PdpUpdate update = updates.remove(0);
297 assertEquals(groupName, update.getPdpGroup());
298 assertEquals(pdpType, update.getPdpSubgroup());
299 assertEquals(pdpName, update.getName());
300 assertTrue(update.getPolicies().contains(policy1));
304 * Loads a standard request.
306 * @return a standard request
308 protected ToscaPolicyIdentifierOptVersion loadRequest() {
309 return loadRequest("requestBase.json");
313 * Loads a request from a JSON file.
315 * @param fileName name of the file from which to load
316 * @return the request that was loaded
318 protected ToscaPolicyIdentifierOptVersion loadRequest(String fileName) {
319 return loadFile(fileName, ToscaPolicyIdentifierOptVersion.class);
323 * Loads an empty request.
325 * @return an empty request
327 protected ToscaPolicyIdentifierOptVersion loadEmptyRequest() {
328 return loadRequest("emptyRequestBase.json");
332 * Handles a request by invoking the provider's processPolicy method.
334 * @param data session data
335 * @param request request to be handled
336 * @throws PfModelException if an error occurred
338 private void handle(SessionData data, ToscaPolicyIdentifierOptVersion request) throws PfModelException {
339 prov.processPolicy(data, request);
343 private static class MyProvider extends ProviderBase {
345 * Used to determine whether or not to make an update when
346 * {@link #makeUpdater(ToscaPolicy)} is called. The updater function removes an
347 * item from this queue each time it is invoked.
349 private final Queue<Boolean> shouldUpdate = new LinkedList<>();
352 * Constructs the object and queues up several successful updates.
354 public MyProvider() {
355 for (int x = 0; x < 10; ++x) {
356 shouldUpdate.add(true);
360 public void clear() {
361 shouldUpdate.clear();
364 public void add(Boolean... update) {
365 shouldUpdate.addAll(Arrays.asList(update));
369 protected Updater makeUpdater(SessionData data, ToscaPolicy policy,
370 ToscaPolicyIdentifierOptVersion desiredPolicy) {
372 return (group, subgroup) -> {
373 if (shouldUpdate.remove()) {
374 // queue indicated that the update should succeed
375 subgroup.getPolicies().add(policy.getIdentifier());
377 data.trackDeploy(policy.getIdentifier(), Collections.singleton(PDP1));
378 data.trackUndeploy(policy.getIdentifier(), Collections.singleton(PDP2));
380 ToscaPolicyIdentifier ident2 = new ToscaPolicyIdentifier(POLICY1_NAME, "9.9.9");
381 data.trackDeploy(ident2, Collections.singleton(PDP3));
382 data.trackUndeploy(ident2, Collections.singleton(PDP4));
386 // queue indicated that no update should be made this time