Move PAP database provider to spring boot default
[policy/pap.git] / main / src / test / java / org / onap / policy / pap / main / rest / TestPdpGroupDeployProvider.java
1 /*
2  * ============LICENSE_START=======================================================
3  * ONAP PAP
4  * ================================================================================
5  * Copyright (C) 2019-2022 AT&T Intellectual Property. All rights reserved.
6  * Modifications Copyright (C) 2021 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
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
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=========================================================
21  */
22
23 package org.onap.policy.pap.main.rest;
24
25 import static org.assertj.core.api.Assertions.assertThat;
26 import static org.assertj.core.api.Assertions.assertThatCode;
27 import static org.assertj.core.api.Assertions.assertThatThrownBy;
28 import static org.junit.Assert.assertEquals;
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;
33
34 import java.util.ArrayList;
35 import java.util.Arrays;
36 import java.util.Collections;
37 import java.util.List;
38 import java.util.stream.Collectors;
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.PdpDeployPolicies;
47 import org.onap.policy.models.pdp.concepts.DeploymentGroup;
48 import org.onap.policy.models.pdp.concepts.DeploymentGroups;
49 import org.onap.policy.models.pdp.concepts.DeploymentSubGroup;
50 import org.onap.policy.models.pdp.concepts.DeploymentSubGroup.Action;
51 import org.onap.policy.models.pdp.concepts.PdpGroup;
52 import org.onap.policy.models.pdp.concepts.PdpGroups;
53 import org.onap.policy.models.pdp.concepts.PdpSubGroup;
54 import org.onap.policy.models.pdp.concepts.PdpUpdate;
55 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
56 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
57 import org.onap.policy.pap.main.PapConstants;
58
59 public class TestPdpGroupDeployProvider extends ProviderSuper {
60
61     private static final String EXPECTED_EXCEPTION = "expected exception";
62
63     private static final String POLICY2_NAME = "policyB";
64     private static final String POLICY3_NAME = "policyC";
65     private static final String POLICY1_VERSION = "1.2.3";
66     private static final String POLICY2_VERSION = "1.2.3";
67     private static final String POLICY3_VERSION = "1.2.3";
68     private static final String GROUP1_NAME = "groupA";
69     private static final String PDP1_TYPE = "pdpTypeA";
70     private static final String PDP2_TYPE = "pdpTypeB";
71     private static final String PDP4_TYPE = "pdpTypeD";
72     private static final String PDP2 = "pdpB";
73     private static final String PDP4 = "pdpD";
74
75     private PdpGroupDeployProvider prov;
76
77     @AfterClass
78     public static void tearDownAfterClass() {
79         Registry.newRegistry();
80     }
81
82     /**
83      * Configures mocks and objects.
84      *
85      * @throws Exception if an error occurs
86      */
87     @Override
88     @Before
89     public void setUp() throws Exception {
90
91         super.setUp();
92         prov = new PdpGroupDeployProvider();
93         super.initialize(prov);
94
95         when(toscaService.getFilteredPolicyList(any())).thenReturn(loadPolicies("daoPolicyList2.json"));
96         when(toscaService.getPolicyTypeList("typeA", "100.2.3"))
97             .thenReturn(Arrays.asList(loadPolicyType("daoPolicyType.json")));
98     }
99
100     /**
101      * Tests updateGroupPolicies when policies are being added.
102      */
103     @Test
104     public void testUpdateGroupPoliciesAdd() throws Exception {
105         PdpGroups groups = loadPdpGroups("deployGroups.json");
106         PdpGroup newgrp = groups.getGroups().get(0);
107         PdpGroup dbgroup = new PdpGroup(newgrp);
108         when(pdpGroupService.getPdpGroups(dbgroup.getName())).thenReturn(Arrays.asList(dbgroup));
109
110         // add new policies
111         List<ToscaConceptIdentifier> policies = newgrp.getPdpSubgroups().get(0).getPolicies();
112         policies.add(new ToscaConceptIdentifier(POLICY2_NAME, POLICY2_VERSION));
113         policies.add(new ToscaConceptIdentifier(POLICY3_NAME, POLICY3_VERSION));
114
115         when(toscaService.getFilteredPolicyList(any())).thenReturn(loadPolicies("createGroupNewPolicy.json"))
116                 .thenReturn(loadPolicies("createGroupNewPolicy2.json")).thenReturn(loadPolicies("daoPolicyList.json"));
117
118         // add = POST
119         DeploymentGroups depgroups = toDeploymentGroups(groups);
120         depgroups.getGroups().get(0).getDeploymentSubgroups().get(0).setAction(Action.POST);
121
122         prov.updateGroupPolicies(depgroups, DEFAULT_USER);
123
124         assertEquals(newgrp.toString(), dbgroup.toString());
125         assertGroupUpdate(dbgroup, dbgroup.getPdpSubgroups().get(0));
126     }
127
128     /**
129      * Tests updateGroupPolicies when policies are being deleted.
130      */
131     @Test
132     public void testUpdateGroupPoliciesDelete() throws Exception {
133         PdpGroups groups = loadPdpGroups("deployGroups.json");
134         PdpGroup newgrp = groups.getGroups().get(0);
135
136         // additional policies in the DB that will be removed
137         List<ToscaConceptIdentifier> policies = newgrp.getPdpSubgroups().get(0).getPolicies();
138         policies.add(new ToscaConceptIdentifier(POLICY2_NAME, POLICY2_VERSION));
139         policies.add(new ToscaConceptIdentifier(POLICY3_NAME, POLICY3_VERSION));
140
141         PdpGroup dbgroup = new PdpGroup(newgrp);
142         when(pdpGroupService.getPdpGroups(dbgroup.getName())).thenReturn(Arrays.asList(dbgroup));
143
144         // policy that should be left
145         final ToscaConceptIdentifier policyId1 = policies.remove(0);
146
147         when(toscaService.getFilteredPolicyList(any())).thenReturn(loadPolicies("createGroupNewPolicy.json"))
148                 .thenReturn(loadPolicies("createGroupNewPolicy2.json")).thenReturn(loadPolicies("daoPolicyList.json"));
149
150         DeploymentGroups depgroups = toDeploymentGroups(groups);
151         depgroups.getGroups().get(0).getDeploymentSubgroups().get(0).setAction(Action.DELETE);
152
153         prov.updateGroupPolicies(depgroups, DEFAULT_USER);
154
155         // only the first policy should remain
156         policies.clear();
157         policies.add(policyId1);
158
159         assertEquals(newgrp.toString(), dbgroup.toString());
160         assertGroupUpdate(dbgroup, dbgroup.getPdpSubgroups().get(0));
161     }
162
163     /**
164      * Tests updateGroupPolicies when policies are being added and deleted in the same
165      * subgroup.
166      */
167     @Test
168     public void testUpdateGroupPoliciesAddAndDelete() throws Exception {
169         PdpGroups groups = loadPdpGroups("deployGroups.json");
170         PdpGroup newgrp = groups.getGroups().get(0);
171         PdpSubGroup subgrp = newgrp.getPdpSubgroups().get(0);
172
173         // put policy3 into db subgroup
174         subgrp.getPolicies().add(new ToscaConceptIdentifier(POLICY3_NAME, POLICY3_VERSION));
175         PdpGroup dbgroup = new PdpGroup(newgrp);
176         when(pdpGroupService.getPdpGroups(dbgroup.getName())).thenReturn(Arrays.asList(dbgroup));
177
178         // now make the subgrp reflect our final expectation
179         subgrp.getPolicies().remove(1);
180         subgrp.getPolicies().add(new ToscaConceptIdentifier(POLICY2_NAME, POLICY2_VERSION));
181
182         // indicate policy2 being added and policy3 being deleted
183         DeploymentSubGroup depsub1 = new DeploymentSubGroup();
184         depsub1.setAction(Action.POST);
185         depsub1.setPdpType(subgrp.getPdpType());
186         depsub1.setPolicies(Arrays.asList(new ToscaConceptIdentifier(POLICY2_NAME, POLICY2_VERSION)));
187
188         DeploymentSubGroup depsub2 = new DeploymentSubGroup();
189         depsub2.setAction(Action.DELETE);
190         depsub2.setPdpType(subgrp.getPdpType());
191         depsub2.setPolicies(Arrays.asList(new ToscaConceptIdentifier(POLICY3_NAME, POLICY3_VERSION)));
192
193         DeploymentGroup depgroup = new DeploymentGroup();
194         depgroup.setName(newgrp.getName());
195         depgroup.setDeploymentSubgroups(Arrays.asList(depsub1, depsub2));
196
197         DeploymentGroups depgroups = new DeploymentGroups();
198         depgroups.setGroups(Arrays.asList(depgroup));
199
200         when(toscaService.getFilteredPolicyList(any())).thenReturn(loadPolicies("createGroupNewPolicy.json"))
201                 .thenReturn(loadPolicies("daoPolicyList.json")).thenReturn(loadPolicies("createGroupNewPolicy2.json"));
202
203         prov.updateGroupPolicies(depgroups, DEFAULT_USER);
204
205         assertEquals(newgrp.toString(), dbgroup.toString());
206         assertGroupUpdate(dbgroup, dbgroup.getPdpSubgroups().get(0));
207     }
208
209     @Test
210     public void testUpdateGroupPolicies() throws Exception {
211         PdpGroups groups = loadPdpGroups("deployGroups.json");
212         PdpGroup newgrp = groups.getGroups().get(0);
213         PdpGroup group = new PdpGroup(newgrp);
214         when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
215
216         // something different in this subgroup
217         group.getPdpSubgroups().get(0).getPolicies().add(new ToscaConceptIdentifier(POLICY2_NAME, POLICY2_VERSION));
218
219         prov.updateGroupPolicies(toDeploymentGroups(groups), DEFAULT_USER);
220
221         assertEquals(newgrp.toString(), group.toString());
222         assertGroupUpdate(group, group.getPdpSubgroups().get(0));
223     }
224
225     @Test
226     public void testUpdateGroupPolicies_EmptyRequest() throws Exception {
227         prov.updateGroupPolicies(toDeploymentGroups(loadPdpGroups("emptyGroups.json")), DEFAULT_USER);
228
229         // no groups, so no action should have been taken
230         assertNoGroupAction();
231     }
232
233     @Test
234     public void testUpdateGroupPolicies_InvalidRequest() throws Exception {
235         assertThatThrownBy(() -> prov.updateGroupPolicies(new DeploymentGroups(), DEFAULT_USER))
236                 .isInstanceOf(PfModelException.class).hasMessageContaining("is null");
237
238         assertNoGroupAction();
239     }
240
241     @Test
242     public void testUpdateGroup_UnknownGroup() throws Exception {
243         PdpGroups groups = loadPdpGroups("deployGroups.json");
244
245         String groupName = groups.getGroups().get(0).getName();
246
247         // group not found
248         when(pdpGroupService.getPdpGroups(groupName)).thenReturn(Collections.emptyList());
249
250         assertThatThrownBy(() -> prov.updateGroupPolicies(toDeploymentGroups(groups), DEFAULT_USER))
251                 .isInstanceOf(PfModelException.class).hasMessageContaining(groupName)
252                 .hasMessageContaining("unknown group");
253
254         assertNoGroupAction();
255     }
256
257     @Test
258     public void testUpdateGroup() throws Exception {
259         PdpGroups groups = loadPdpGroups("deployGroups.json");
260
261         // DB group = new group
262         PdpGroup group = new PdpGroup(groups.getGroups().get(0));
263         when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
264
265         prov.updateGroupPolicies(toDeploymentGroups(groups), DEFAULT_USER);
266
267         assertNoGroupAction();
268     }
269
270     @Test
271     public void testUpdateGroup_NewSubGroup() throws Exception {
272         PdpGroups groups = loadPdpGroups("createGroupsNewSub.json");
273         PdpGroup group = loadPdpGroups("deployGroups.json").getGroups().get(0);
274         when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
275
276         assertThatThrownBy(() -> prov.updateGroupPolicies(toDeploymentGroups(groups), DEFAULT_USER))
277                 .isInstanceOf(PfModelException.class).hasMessageContaining("pdpTypeB")
278                 .hasMessageContaining("unknown subgroup");
279
280         assertNoGroupAction();
281     }
282
283     @Test
284     public void testUpdateGroup_UpdatedSubGroup() throws Exception {
285         PdpGroups groups = loadPdpGroups("deployGroups.json");
286         PdpGroup newgrp = groups.getGroups().get(0);
287         PdpGroup group = new PdpGroup(newgrp);
288         when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
289
290         // something different in this subgroup
291         group.getPdpSubgroups().get(0).getPolicies().add(new ToscaConceptIdentifier(POLICY2_NAME, POLICY2_VERSION));
292
293         prov.updateGroupPolicies(toDeploymentGroups(groups), DEFAULT_USER);
294
295         assertEquals(newgrp.toString(), group.toString());
296         assertGroupUpdate(group, group.getPdpSubgroups().get(0));
297     }
298
299     @Test
300     public void testUpdateSubGroup_Invalid() throws Exception {
301         PdpGroups groups = loadPdpGroups("deployGroups.json");
302         PdpGroup newgrp = groups.getGroups().get(0);
303         PdpGroup group = new PdpGroup(newgrp);
304
305         // group has no policies yet
306         group.getPdpSubgroups().get(0).getPolicies().clear();
307         when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
308
309         // unknown policy
310         when(toscaService.getFilteredPolicyList(any())).thenReturn(Collections.emptyList());
311
312         assertThatThrownBy(() -> prov.updateGroupPolicies(toDeploymentGroups(groups), DEFAULT_USER))
313                 .isInstanceOf(PfModelException.class)
314                 .hasMessageContaining(newgrp.getPdpSubgroups().get(0).getPolicies().get(0).getName())
315                 .hasMessageContaining("unknown policy");
316
317         assertNoGroupAction();
318     }
319
320     @Test
321     public void testUpdateSubGroup_Policies() throws Exception {
322         PdpGroups groups = loadPdpGroups("deployGroups.json");
323         PdpGroup newgrp = groups.getGroups().get(0);
324
325         // add a second subgroup, which will be left unchanged
326         PdpSubGroup subgrp = newgrp.getPdpSubgroups().get(0);
327         PdpSubGroup subgrp2 = new PdpSubGroup(subgrp);
328         subgrp2.setPdpType(PDP2_TYPE);
329         newgrp.getPdpSubgroups().add(subgrp2);
330
331         PdpGroup group = new PdpGroup(newgrp);
332         when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
333
334         // add two new policies
335         ToscaConceptIdentifier policyId2 = new ToscaConceptIdentifier(POLICY2_NAME, POLICY2_VERSION);
336         subgrp.getPolicies().add(policyId2);
337
338         ToscaConceptIdentifier policyId3 = new ToscaConceptIdentifier(POLICY3_NAME, POLICY3_VERSION);
339         subgrp.getPolicies().add(policyId3);
340
341         when(toscaService.getFilteredPolicyList(any())).thenReturn(loadPolicies("createGroupNewPolicy.json"))
342                 .thenReturn(loadPolicies("createGroupNewPolicy2.json")).thenReturn(loadPolicies("daoPolicyList.json"));
343
344         prov.updateGroupPolicies(toDeploymentGroups(groups), DEFAULT_USER);
345
346         Collections.sort(newgrp.getPdpSubgroups().get(0).getPolicies());
347         Collections.sort(group.getPdpSubgroups().get(0).getPolicies());
348
349         assertEquals(newgrp.toString(), group.toString());
350
351         // nothing is complete - notification should be empty
352         checkEmptyNotification();
353
354         // this requires a PDP UPDATE message
355         assertGroupUpdate(newgrp, subgrp);
356     }
357
358     @Test
359     public void testUpdateSubGroup_PolicyVersionPrefix() throws Exception {
360         PdpGroups groups = loadPdpGroups("deployGroups.json");
361         PdpGroup newgrp = groups.getGroups().get(0);
362
363         PdpGroup group = new PdpGroup(newgrp);
364         when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
365
366         // use version prefix
367         PdpSubGroup subgrp = newgrp.getPdpSubgroups().get(0);
368         ToscaConceptIdentifier ident = subgrp.getPolicies().get(0);
369         String version = ident.getVersion();
370         ident.setVersion("1");
371
372         prov.updateGroupPolicies(toDeploymentGroups(groups), DEFAULT_USER);
373
374         // restore full type before comparing
375         ident.setVersion(version);
376
377         Collections.sort(newgrp.getPdpSubgroups().get(0).getPolicies());
378         Collections.sort(group.getPdpSubgroups().get(0).getPolicies());
379
380         assertEquals(newgrp.toString(), group.toString());
381
382         assertNoGroupAction();
383     }
384
385     @Test
386     public void testUpdateSubGroup_PolicyVersionPrefixMismatch() throws Exception {
387         PdpGroups groups = loadPdpGroups("deployGroups.json");
388         PdpGroup newgrp = groups.getGroups().get(0);
389
390         PdpGroup group = new PdpGroup(newgrp);
391         when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
392
393         // use incorrect version prefix
394         newgrp.getPdpSubgroups().get(0).getPolicies().get(0).setVersion("9");
395
396         assertThatThrownBy(() -> prov.updateGroupPolicies(toDeploymentGroups(groups), DEFAULT_USER))
397                 .isInstanceOf(PfModelException.class).hasMessageContaining("different version already deployed");
398
399         assertNoGroupAction();
400     }
401
402     @Test
403     public void testUpdateSubGroup_Unchanged() throws Exception {
404         PdpGroups dbgroups = loadPdpGroups("deployGroups.json");
405         PdpGroup newgrp = dbgroups.getGroups().get(0);
406         PdpGroup group = new PdpGroup(newgrp);
407         when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
408
409         prov.updateGroupPolicies(toDeploymentGroups(dbgroups), DEFAULT_USER);
410
411         Collections.sort(newgrp.getPdpSubgroups().get(0).getPolicies());
412         Collections.sort(group.getPdpSubgroups().get(0).getPolicies());
413
414         assertEquals(newgrp.toString(), group.toString());
415
416         // no notifications
417         checkEmptyNotification();
418
419         // no group updates
420         assertNoGroupAction();
421     }
422
423     @Test
424     public void testUpdateSubGroup_PolicyVersionMismatch() throws Exception {
425         PdpGroups dbgroups = loadPdpGroups("deployGroups.json");
426         PdpGroup newgrp = dbgroups.getGroups().get(0);
427         PdpGroup dbgroup = new PdpGroup(newgrp);
428         when(pdpGroupService.getPdpGroups(dbgroup.getName())).thenReturn(Arrays.asList(dbgroup));
429
430         // arrange for DB policy version to be different
431         PdpSubGroup dbsubgrp = dbgroup.getPdpSubgroups().get(0);
432         dbsubgrp.getPolicies().get(0).setVersion("9.9.9");
433
434         when(toscaService.getFilteredPolicyList(any())).thenReturn(loadPolicies("daoPolicyList.json"));
435
436         assertThatThrownBy(() -> prov.updateGroupPolicies(toDeploymentGroups(dbgroups), DEFAULT_USER))
437                 .isInstanceOf(PfModelException.class).hasMessageContaining("different version already deployed");
438
439         assertNoGroupAction();
440     }
441
442     @Test
443     public void testUpdateSubGroup_UnsupportedType() throws Exception {
444         PdpGroups dbgroups = loadPdpGroups("deployGroups.json");
445         PdpGroup newgrp = dbgroups.getGroups().get(0);
446         PdpGroup dbgroup = new PdpGroup(newgrp);
447         when(pdpGroupService.getPdpGroups(dbgroup.getName())).thenReturn(Arrays.asList(dbgroup));
448
449         final DeploymentGroups groups = toDeploymentGroups(dbgroups);
450
451         PdpSubGroup dbsubgrp = dbgroup.getPdpSubgroups().get(0);
452
453         // DB has no policies
454         dbsubgrp.getPolicies().clear();
455
456         // DB has a different supported type
457         dbsubgrp.getSupportedPolicyTypes().get(0).setName("some-other-type");
458
459         when(toscaService.getFilteredPolicyList(any())).thenReturn(loadPolicies("daoPolicyList.json"));
460
461         assertThatThrownBy(() -> prov.updateGroupPolicies(groups, DEFAULT_USER)).isInstanceOf(PfModelException.class)
462                 .hasMessageContaining(newgrp.getPdpSubgroups().get(0).getPolicies().get(0).getName())
463                 .hasMessageContaining("not a supported policy for the subgroup");
464
465         assertNoGroupAction();
466     }
467
468     @Test
469     public void testDeployPolicies() throws PfModelException {
470         assertThatCode(() -> prov.deployPolicies(loadEmptyRequest(), DEFAULT_USER)).doesNotThrowAnyException();
471     }
472
473     /**
474      * Tests deployPolicies() when the policies are invalid.
475      */
476     @Test
477     public void testDeployPoliciesInvalidPolicies() throws Exception {
478         // valid list
479         PdpDeployPolicies policies0 = loadFile("PapPoliciesList.json", PdpDeployPolicies.class);
480         assertThatCode(() -> prov.deployPolicies(policies0, DEFAULT_USER)).doesNotThrowAnyException();
481
482         // null list
483         PdpDeployPolicies policies = new PdpDeployPolicies();
484         assertThatThrownBy(() -> prov.deployPolicies(policies, DEFAULT_USER)).isInstanceOf(PfModelException.class)
485                 .hasMessageContaining("policies");
486
487         // list containing null item
488         PdpDeployPolicies policies2 = loadFile("PapPoliciesNullItem.json", PdpDeployPolicies.class);
489         assertThatThrownBy(() -> prov.deployPolicies(policies2, DEFAULT_USER)).isInstanceOf(PfModelException.class)
490                 .hasMessageContaining("policies").hasMessageContaining("null");
491
492         // list containing a policy with a null name
493         PdpDeployPolicies policies3 = loadFile("PapPoliciesNullPolicyName.json", PdpDeployPolicies.class);
494         assertThatThrownBy(() -> prov.deployPolicies(policies3, DEFAULT_USER)).isInstanceOf(PfModelException.class)
495                 .hasMessageContaining("policies").hasMessageContaining("policy-id").hasMessageContaining("null")
496                 .hasMessageNotContaining("\"value\"");
497
498         // list containing a policy with an invalid name
499         PdpDeployPolicies policies4 = loadFile("PapPoliciesInvalidPolicyName.json", PdpDeployPolicies.class);
500         assertThatThrownBy(() -> prov.deployPolicies(policies4, DEFAULT_USER)).isInstanceOf(PfModelException.class)
501                 .hasMessageContaining("policies").hasMessageContaining("policy-id").hasMessageContaining("$ abc")
502                 .hasMessageNotContaining("version");
503
504         // list containing a policy with an invalid version
505         PdpDeployPolicies policies5 = loadFile("PapPoliciesInvalidPolicyVersion.json", PdpDeployPolicies.class);
506         assertThatThrownBy(() -> prov.deployPolicies(policies5, DEFAULT_USER)).isInstanceOf(PfModelException.class)
507                 .hasMessageContaining("policies").hasMessageContaining("version").hasMessageContaining("abc123")
508                 .hasMessageNotContaining("policy-id");
509     }
510
511     /**
512      * Tests deployPolicies() when the supported policy type uses a wild-card.
513      *
514      * @throws Exception if an error occurs
515      */
516     @Test
517     public void testDeployPoliciesWildCard() throws Exception {
518         when(pdpGroupService.getFilteredPdpGroups(any())).thenReturn(loadGroups("deployPoliciesWildCard.json"));
519         when(toscaService.getFilteredPolicyList(any())).thenReturn(loadPolicies("daoPolicyListWildCard.json"));
520         when(toscaService.getPolicyTypeList(any(), any())).thenReturn(Collections.emptyList());
521
522         policy1.setName("policy.some");
523         policy1.setVersion(POLICY1_VERSION);
524         policy1.setType("some.type");
525         policy1.setTypeVersion("100.2.3");
526
527         PdpDeployPolicies depreq = loadRequest();
528         depreq.getPolicies().get(0).setName("policy.some");
529
530         prov.deployPolicies(depreq, DEFAULT_USER);
531
532         assertGroup(getGroupUpdates(), GROUP1_NAME);
533
534         List<PdpUpdate> requests = getUpdateRequests(1);
535         assertUpdate(requests, GROUP1_NAME, PDP2_TYPE, PDP2);
536
537         // nothing is complete - notification should be empty
538         checkEmptyNotification();
539     }
540
541     @Test
542     public void testDeploySimplePolicies() throws Exception {
543         assertThatCode(() -> prov.deployPolicies(loadEmptyRequest(), DEFAULT_USER)).doesNotThrowAnyException();
544     }
545
546     @Test
547     public void testDeploySimplePolicies_PfRtEx() throws Exception {
548         PfModelRuntimeException exc = new PfModelRuntimeException(Status.BAD_REQUEST, EXPECTED_EXCEPTION);
549         when(pdpGroupService.getFilteredPdpGroups(any())).thenThrow(exc);
550
551         assertThatThrownBy(() -> prov.deployPolicies(loadRequest(), DEFAULT_USER)).isSameAs(exc);
552     }
553
554     @Test
555     public void testDeploySimplePolicies_RuntimeEx() throws Exception {
556         RuntimeException exc = new RuntimeException(EXPECTED_EXCEPTION);
557         when(toscaService.getFilteredPolicyList(any())).thenThrow(exc);
558
559         assertThatThrownBy(() -> prov.deployPolicies(loadRequest(), DEFAULT_USER)).isInstanceOf(PfModelException.class)
560                 .hasCause(exc);
561     }
562
563     @Test
564     public void testDeploySimplePolicies_NoGroups() throws Exception {
565         when(pdpGroupService.getFilteredPdpGroups(any())).thenReturn(loadGroups("emptyGroups.json"));
566
567         assertThatThrownBy(() -> prov.deployPolicies(loadRequest(), DEFAULT_USER)).isInstanceOf(PfModelException.class)
568                 .hasMessage("policy not supported by any PDP group: policyA 1.2.3");
569     }
570
571     /**
572      * Tests PapStatisticsManager counts when policies are added to a subgroup.
573      *
574      * @throws Exception if an error occurs
575      */
576     @Test
577     public void testDeployedPdpGroupCountStatistics() throws Exception {
578         Registry.unregister(PapConstants.REG_STATISTICS_MANAGER);
579         PapStatisticsManager mgr = new PapStatisticsManager();
580         Registry.register(PapConstants.REG_STATISTICS_MANAGER, mgr);
581
582         when(pdpGroupService.getFilteredPdpGroups(any())).thenReturn(loadGroups("deployPoliciesWildCard.json"));
583         prov.deployPolicies(loadRequest("multiple_requests.json"), DEFAULT_USER);
584         assertEquals(3, mgr.getTotalPolicyDeployCount());
585
586         Registry.unregister(PapConstants.REG_STATISTICS_MANAGER);
587         Registry.register(PapConstants.REG_STATISTICS_MANAGER, statsmanager);
588     }
589
590     @Test
591     public void testMakeUpdater() throws Exception {
592         /*
593          * Each subgroup has a different PDP type and name.
594          *
595          * Type is not supported by the first subgroup.
596          *
597          * Second subgroup matches.
598          *
599          * Third subgroup already contains the policy.
600          *
601          * Last subgroup matches.
602          */
603
604         when(pdpGroupService.getFilteredPdpGroups(any())).thenReturn(loadGroups("upgradeGroupDao.json"));
605
606         prov.deployPolicies(loadRequest(), DEFAULT_USER);
607
608         assertGroup(getGroupUpdates(), GROUP1_NAME);
609
610         List<PdpUpdate> requests = getUpdateRequests(2);
611         assertUpdate(requests, GROUP1_NAME, PDP2_TYPE, PDP2);
612         assertUpdate(requests, GROUP1_NAME, PDP4_TYPE, PDP4);
613
614         // nothing is complete - notification should be empty
615         checkEmptyNotification();
616     }
617
618     @Test
619     public void testMakeUpdater_PolicyVersionMismatch() throws Exception {
620
621         // subgroup has a different version of the Policy
622         when(pdpGroupService.getFilteredPdpGroups(any())).thenReturn(loadGroups("upgradeGroupDao_DiffVers.json"));
623
624         PdpDeployPolicies req = loadRequest();
625         assertThatThrownBy(() -> prov.deployPolicies(req, DEFAULT_USER)).isInstanceOf(PfModelRuntimeException.class)
626                 .hasMessageContaining("pdpTypeC").hasMessageContaining("different version already deployed");
627
628         verify(pdpGroupService, never()).createPdpGroups(any());
629         verify(pdpGroupService, never()).updatePdpGroups(any());
630         verify(reqmap, never()).addRequest(any(PdpUpdate.class));
631     }
632
633     @Test
634     public void testMakeUpdater_NoPdps() throws Exception {
635
636         // subgroup has no PDPs
637         when(pdpGroupService.getFilteredPdpGroups(any())).thenReturn(loadGroups("upgradeGroup_NoPdpsDao.json"));
638
639         PdpDeployPolicies req = loadRequest();
640         assertThatThrownBy(() -> prov.deployPolicies(req, DEFAULT_USER)).isInstanceOf(PfModelRuntimeException.class)
641                 .hasMessage("group " + GROUP1_NAME + " subgroup " + PDP1_TYPE + " has no active PDPs");
642
643         verify(pdpGroupService, never()).createPdpGroups(any());
644         verify(pdpGroupService, never()).updatePdpGroups(any());
645         verify(reqmap, never()).addRequest(any(PdpUpdate.class));
646     }
647
648     protected void assertUpdate(List<PdpUpdate> updates, String groupName, String pdpType, String pdpName) {
649
650         PdpUpdate update = updates.remove(0);
651
652         assertEquals(groupName, update.getPdpGroup());
653         assertEquals(pdpType, update.getPdpSubgroup());
654         assertEquals(pdpName, update.getName());
655         assertThat(update.getPoliciesToBeDeployed()).contains(policy1);
656     }
657
658     private void assertNoGroupAction() throws Exception {
659         verify(pdpGroupService, never()).createPdpGroups(any());
660         verify(pdpGroupService, never()).updatePdpGroups(any());
661         verify(reqmap, never()).addRequest(any(), any());
662     }
663
664     private void assertGroupUpdate(PdpGroup group, PdpSubGroup subgrp) throws Exception {
665         verify(pdpGroupService, never()).createPdpGroups(any());
666
667         assertEquals(0, getStateChangeRequests(1).size());
668
669         List<PdpUpdate> pdpUpdates = getUpdateRequests(1);
670         assertEquals(1, pdpUpdates.size());
671
672         PdpUpdate pdpUpdate = pdpUpdates.get(0);
673         assertEquals("pdpA", pdpUpdate.getName());
674         assertEquals(group.getName(), pdpUpdate.getPdpGroup());
675
676         assertEquals(subgrp.getPdpType(), pdpUpdate.getPdpSubgroup());
677
678         List<ToscaConceptIdentifier> pdpPolicies = pdpUpdate.getPoliciesToBeDeployed().stream()
679                 .map(ToscaPolicy::getIdentifier).collect(Collectors.toList());
680         Collections.sort(pdpPolicies);
681
682         assertThat(subgrp.getPolicies()).containsAll(pdpPolicies);
683
684         List<PdpGroup> updates = getGroupUpdates();
685         assertEquals(Arrays.asList(group), updates);
686     }
687
688     /**
689      * Loads a standard request.
690      *
691      * @return a standard request
692      */
693     protected PdpDeployPolicies loadRequest() {
694         return loadRequest("request.json");
695     }
696
697     /**
698      * Loads a request from a JSON file.
699      *
700      * @param fileName name of the file from which to load
701      * @return the request that was loaded
702      */
703     protected PdpDeployPolicies loadRequest(String fileName) {
704         return loadFile(fileName, PdpDeployPolicies.class);
705     }
706
707     /**
708      * Loads an empty request.
709      *
710      * @return an empty request
711      */
712     protected PdpDeployPolicies loadEmptyRequest() {
713         return loadRequest("emptyRequest.json");
714     }
715
716     private DeploymentGroups toDeploymentGroups(PdpGroups dbgroups) {
717         DeploymentGroups groups = new DeploymentGroups();
718
719         groups.setGroups(dbgroups.getGroups().stream().map(this::toDeploymentGroup).collect(Collectors.toList()));
720
721         return groups;
722     }
723
724     private DeploymentGroup toDeploymentGroup(PdpGroup dbgroup) {
725         DeploymentGroup group = new DeploymentGroup();
726
727         group.setName(dbgroup.getName());
728         group.setDeploymentSubgroups(
729                 dbgroup.getPdpSubgroups().stream().map(this::toDeploymentSubGroup).collect(Collectors.toList()));
730
731         return group;
732     }
733
734     private DeploymentSubGroup toDeploymentSubGroup(PdpSubGroup dbsubgrp) {
735         DeploymentSubGroup subgrp = new DeploymentSubGroup();
736
737         subgrp.setAction(Action.PATCH);
738         subgrp.setPdpType(dbsubgrp.getPdpType());
739         subgrp.setPolicies(new ArrayList<>(dbsubgrp.getPolicies()));
740
741         return subgrp;
742     }
743 }