2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2019-2021 AT&T Intellectual Property. All rights reserved.
6 * Modifications Copyright (C) 2021,2023 Nordix Foundation.
7 * Modifications Copyright (C) 2021-2022 Bell Canada. All rights reserved.
8 * ================================================================================
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 * ============LICENSE_END=========================================================
23 package org.onap.policy.pap.main.rest;
25 import static org.assertj.core.api.Assertions.assertThatThrownBy;
26 import static org.junit.Assert.assertEquals;
27 import static org.junit.Assert.assertSame;
28 import static org.junit.Assert.assertTrue;
29 import static org.mockito.ArgumentMatchers.any;
30 import static org.mockito.Mockito.never;
31 import static org.mockito.Mockito.verify;
32 import static org.mockito.Mockito.when;
34 import java.util.Arrays;
35 import java.util.Collections;
36 import java.util.LinkedList;
37 import java.util.List;
38 import java.util.Queue;
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.onap.policy.common.utils.services.Registry;
44 import org.onap.policy.models.base.PfModelException;
45 import org.onap.policy.models.base.PfModelRuntimeException;
46 import org.onap.policy.models.pap.concepts.PapPolicyIdentifier;
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.ToscaConceptIdentifier;
51 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifierOptVersion;
52 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
53 import org.onap.policy.pap.main.PapConstants;
54 import org.springframework.test.util.ReflectionTestUtils;
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;
75 public static void tearDownAfterClass() {
76 Registry.newRegistry();
80 * Configures mocks and objects.
82 * @throws Exception if an error occurs
86 public void setUp() throws Exception {
88 prov = new MyProvider();
89 super.initialize(prov);
90 when(toscaService.getFilteredPolicyList(any())).thenReturn(loadPolicies("daoPolicyList.json"));
94 public void testProviderBase() {
95 assertSame(lockit, ReflectionTestUtils.getField(prov, "updateLock"));
96 assertSame(reqmap, ReflectionTestUtils.getField(prov, "requestMap"));
100 public void testProcess() throws Exception {
101 prov.process(loadRequest(), this::handle);
103 assertGroup(getGroupUpdates(), GROUP1_NAME);
105 assertUpdate(getUpdateRequests(1), GROUP1_NAME, PDP1_TYPE, PDP1);
107 checkEmptyNotification();
111 public void testProcess_PfRtEx() throws Exception {
112 PfModelRuntimeException ex = new PfModelRuntimeException(Status.BAD_REQUEST, EXPECTED_EXCEPTION);
113 when(pdpGroupService.updatePdpGroups(any())).thenThrow(ex);
115 assertThatThrownBy(() -> prov.process(loadEmptyRequest(), this::handle)).isSameAs(ex);
119 public void testProcess_RuntimeEx() throws Exception {
120 RuntimeException ex = new RuntimeException(EXPECTED_EXCEPTION);
121 when(pdpGroupService.updatePdpGroups(any())).thenThrow(ex);
123 assertThatThrownBy(() -> prov.process(loadEmptyRequest(), this::handle)).isInstanceOf(PfModelException.class)
124 .hasMessage("request failed").hasCause(ex);
128 public void testProcessPolicy_NoGroups() throws Exception {
129 when(pdpGroupService.getFilteredPdpGroups(any())).thenReturn(Collections.emptyList());
131 SessionData session =
132 new SessionData(DEFAULT_USER, toscaService, pdpGroupService, policyStatusService, policyAuditService);
133 ToscaConceptIdentifierOptVersion ident = new ToscaConceptIdentifierOptVersion(POLICY1_NAME, POLICY1_VERSION);
134 assertThatThrownBy(() -> prov.processPolicy(session, ident)).isInstanceOf(PfModelException.class)
135 .hasMessage("policy not supported by any PDP group: policyA 1.2.3");
140 public void testGetPolicy() throws Exception {
141 PfModelException exc = new PfModelException(Status.CONFLICT, EXPECTED_EXCEPTION);
142 when(toscaService.getFilteredPolicyList(any())).thenThrow(exc);
144 ToscaConceptIdentifierOptVersion req = loadRequest();
145 assertThatThrownBy(() -> prov.process(req, this::handle)).isInstanceOf(PfModelRuntimeException.class)
150 public void testGetPolicy_NotFound() throws Exception {
151 when(toscaService.getFilteredPolicyList(any())).thenReturn(Collections.emptyList());
153 ToscaConceptIdentifierOptVersion req = loadRequest();
154 assertThatThrownBy(() -> prov.process(req, this::handle)).isInstanceOf(PfModelRuntimeException.class)
155 .hasMessage("cannot find policy: policyA 1.2.3")
156 .extracting(ex -> ((PfModelRuntimeException) ex).getErrorResponse().getResponseCode())
157 .isEqualTo(Status.NOT_FOUND);
161 public void testGetGroup() throws Exception {
162 when(pdpGroupService.getFilteredPdpGroups(any())).thenReturn(loadGroups("getGroupDao.json"))
163 .thenReturn(loadGroups("groups.json"));
165 prov.process(loadRequest(), this::handle);
167 assertGroup(getGroupUpdates(), GROUP1_NAME);
171 public void testUpgradeGroup() throws Exception {
173 * Each subgroup has a different PDP type and name.
175 * Type is not supported by the first subgroup.
177 * Second subgroup matches.
179 * Third subgroup already contains the policy.
181 * Last subgroup matches.
184 when(pdpGroupService.getFilteredPdpGroups(any())).thenReturn(loadGroups("upgradeGroupDao.json"));
187 prov.add(false, true, false, true);
189 prov.process(loadRequest(), this::handle);
191 assertGroup(getGroupUpdates(), GROUP1_NAME);
193 List<PdpUpdate> requests = getUpdateRequests(2);
194 assertUpdate(requests, GROUP1_NAME, PDP2_TYPE, PDP2);
195 assertUpdate(requests, GROUP1_NAME, PDP4_TYPE, PDP4);
199 public void testUpgradeGroup_Multiple() throws Exception {
201 * Policy data in the DB: policy1=type1, policy2=type2, policy3=type3,
204 * Group data in the DB: group1=(type1=pdp1, type3=pdp3) group2=(type2=pdp2)
206 * Request specifies: policy1, policy2, policy3, policy4
208 * Should create new versions of group1 and group2.
210 * Should update old versions of group1 and group2. Should also update new version
213 * Should generate updates to pdp1, pdp2, and pdp3.
216 when(toscaService.getFilteredPolicyList(any())).thenReturn(loadPolicies("daoPolicyList.json"))
217 .thenReturn(loadPolicies("upgradeGroupPolicy2.json"))
218 .thenReturn(loadPolicies("upgradeGroupPolicy3.json"))
219 .thenReturn(loadPolicies("upgradeGroupPolicy4.json"));
221 List<PdpGroup> groups1 = loadGroups("upgradeGroupGroup1.json");
222 List<PdpGroup> groups2 = loadGroups("upgradeGroupGroup2.json");
225 * these are in pairs of (get-group, get-max-group) matching each policy in the
229 when(pdpGroupService.getFilteredPdpGroups(any()))
230 .thenReturn(groups1).thenReturn(groups1)
231 .thenReturn(groups2).thenReturn(groups2)
232 .thenReturn(groups1).thenReturn(groups1)
233 .thenReturn(groups1).thenReturn(groups1);
236 // multiple policies in the request
237 PdpDeployPolicies request = loadFile("updateGroupReqMultiple.json", PdpDeployPolicies.class);
239 prov.process(request, (data, deploy) -> {
240 for (ToscaConceptIdentifierOptVersion policy : deploy.getPolicies()) {
241 handle(data, policy);
246 List<PdpGroup> changes = getGroupUpdates();
247 assertGroup(changes, GROUP1_NAME);
248 assertGroup(changes, GROUP2_NAME);
250 List<PdpUpdate> requests = getUpdateRequests(3);
251 assertUpdateIgnorePolicy(requests, GROUP1_NAME, PDP1_TYPE, PDP1);
252 assertUpdateIgnorePolicy(requests, GROUP2_NAME, PDP2_TYPE, PDP2);
253 assertUpdateIgnorePolicy(requests, GROUP1_NAME, PDP3_TYPE, PDP3);
257 public void testUpgradeGroup_NothingUpdated() throws Exception {
261 prov.process(loadRequest(), this::handle);
263 verify(pdpGroupService, never()).createPdpGroups(any());
264 verify(pdpGroupService, never()).updatePdpGroups(any());
265 verify(reqmap, never()).addRequest(any(PdpUpdate.class));
269 protected void assertUpdate(List<PdpUpdate> updates, String groupName, String pdpType, String pdpName) {
271 PdpUpdate update = updates.remove(0);
273 assertEquals(PapConstants.PAP_NAME, update.getSource());
274 assertEquals(groupName, update.getPdpGroup());
275 assertEquals(pdpType, update.getPdpSubgroup());
276 assertEquals(pdpName, update.getName());
277 assertTrue(update.getPoliciesToBeDeployed().contains(policy1));
281 * Loads a standard request.
283 * @return a standard request
285 protected ToscaConceptIdentifierOptVersion loadRequest() {
286 return loadRequest("requestBase.json");
290 * Loads a request from a JSON file.
292 * @param fileName name of the file from which to load
293 * @return the request that was loaded
295 protected ToscaConceptIdentifierOptVersion loadRequest(String fileName) {
296 return loadFile(fileName, PapPolicyIdentifier.class).getGenericIdentifier();
300 * Loads an empty request.
302 * @return an empty request
304 protected ToscaConceptIdentifierOptVersion loadEmptyRequest() {
305 return loadRequest("emptyRequestBase.json");
309 * Handles a request by invoking the provider's processPolicy method.
311 * @param data session data
312 * @param request request to be handled
313 * @throws PfModelException if an error occurred
315 private void handle(SessionData data, ToscaConceptIdentifierOptVersion request) throws PfModelException {
316 prov.processPolicy(data, request);
320 private static class MyProvider extends ProviderBase {
322 * Used to determine whether or not to make an update when
323 * {@link #makeUpdater(ToscaPolicy)} is called. The updater function removes an
324 * item from this queue each time it is invoked.
326 private final Queue<Boolean> shouldUpdate = new LinkedList<>();
329 * Constructs the object and queues up several successful updates.
331 public MyProvider() {
332 for (int x = 0; x < 10; ++x) {
333 shouldUpdate.add(true);
337 public void clear() {
338 shouldUpdate.clear();
341 public void add(Boolean... update) {
342 shouldUpdate.addAll(Arrays.asList(update));
346 protected Updater makeUpdater(SessionData data, ToscaPolicy policy,
347 ToscaConceptIdentifierOptVersion desiredPolicy) {
349 return (group, subgroup) -> {
350 if (shouldUpdate.remove()) {
351 ToscaConceptIdentifier ident1 = policy.getIdentifier();
353 // queue indicated that the update should succeed
354 subgroup.getPolicies().add(ident1);
356 ToscaPolicy testPolicy1 = data.getPolicy(new ToscaConceptIdentifierOptVersion(ident1));
357 data.trackDeploy(testPolicy1, Collections.singleton(PDP1), GROUP1_NAME, PDP1_TYPE);
358 data.trackUndeploy(ident1, Collections.singleton(PDP2), GROUP1_NAME, PDP2_TYPE);
360 ToscaConceptIdentifier ident2 = new ToscaConceptIdentifier(POLICY1_NAME, "9.9.9");
361 ToscaPolicy testPolicy2 = data.getPolicy(new ToscaConceptIdentifierOptVersion(ident2));
362 data.trackDeploy(testPolicy2, Collections.singleton(PDP3), GROUP1_NAME, PDP3_TYPE);
363 data.trackUndeploy(ident2, Collections.singleton(PDP4), GROUP1_NAME, PDP4_TYPE);
367 // queue indicated that no update should be made this time