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