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