Create PAP API to only create/update PdpGroups
[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 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.pap.main.rest;
22
23 import static org.assertj.core.api.Assertions.assertThatThrownBy;
24 import static org.junit.Assert.assertEquals;
25 import static org.junit.Assert.assertSame;
26 import static org.junit.Assert.assertTrue;
27 import static org.mockito.Matchers.any;
28 import static org.mockito.Mockito.never;
29 import static org.mockito.Mockito.verify;
30 import static org.mockito.Mockito.when;
31
32 import java.util.ArrayList;
33 import java.util.Arrays;
34 import java.util.Collections;
35 import java.util.List;
36 import java.util.TreeMap;
37 import java.util.TreeSet;
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.mockito.ArgumentCaptor;
44 import org.onap.policy.common.utils.services.Registry;
45 import org.onap.policy.models.base.PfModelException;
46 import org.onap.policy.models.base.PfModelRuntimeException;
47 import org.onap.policy.models.pap.concepts.PdpDeployPolicies;
48 import org.onap.policy.models.pdp.concepts.PdpGroup;
49 import org.onap.policy.models.pdp.concepts.PdpGroups;
50 import org.onap.policy.models.pdp.concepts.PdpSubGroup;
51 import org.onap.policy.models.pdp.concepts.PdpUpdate;
52 import org.onap.policy.models.pdp.enums.PdpState;
53 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
54 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifier;
55 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier;
56 import org.onap.policy.pap.main.notification.PolicyPdpNotificationData;
57
58 public class TestPdpGroupDeployProvider extends ProviderSuper {
59     private static final String EXPECTED_EXCEPTION = "expected exception";
60
61     private static final String POLICY2_NAME = "policyB";
62     private static final String POLICY1_VERSION = "1.2.3";
63     private static final String GROUP1_NAME = "groupA";
64     private static final String PDP1_TYPE = "pdpTypeA";
65     private static final String PDP2_TYPE = "pdpTypeB";
66     private static final String PDP4_TYPE = "pdpTypeD";
67     private static final String PDP2 = "pdpB";
68     private static final String PDP4 = "pdpD";
69
70     private PdpGroupDeployProvider prov;
71
72
73     @AfterClass
74     public static void tearDownAfterClass() {
75         Registry.newRegistry();
76     }
77
78     /**
79      * Configures mocks and objects.
80      *
81      * @throws Exception if an error occurs
82      */
83     @Override
84     @Before
85     public void setUp() throws Exception {
86
87         super.setUp();
88
89         when(dao.getFilteredPolicyList(any())).thenReturn(loadPolicies("daoPolicyList.json"));
90         when(dao.getPolicyTypeList("typeA", "100.2.3")).thenReturn(Arrays.asList(loadPolicyType("daoPolicyType.json")));
91
92         prov = new PdpGroupDeployProvider();
93     }
94
95     @Test
96     public void testCreateOrUpdateGroups() throws Exception {
97         prov.createOrUpdateGroups(loadPdpGroups("emptyGroups.json"));
98
99         // no groups, so no action should have been taken
100         assertNoGroupAction();
101     }
102
103     @Test
104     public void testCreateOrUpdateGroups_InvalidRequest() throws Exception {
105         assertThatThrownBy(() -> prov.createOrUpdateGroups(new PdpGroups())).isInstanceOf(PfModelException.class)
106                         .hasMessageContaining("is null");
107
108         assertNoGroupAction();
109     }
110
111     @Test
112     public void testCreateOrUpdate_Invalid() throws Exception {
113         PdpGroups groups = loadPdpGroups("createGroups.json");
114         groups.getGroups().get(0).setPdpGroupState(PdpState.TERMINATED);
115
116         assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).isInstanceOf(PfModelException.class)
117                         .hasMessageContaining("pdpGroupState");
118
119         assertNoGroupAction();
120     }
121
122     @Test
123     public void testAddGroup() throws Exception {
124         PdpGroups groups = loadPdpGroups("createGroups.json");
125         PdpGroup group = groups.getGroups().get(0);
126         group.setPdpGroupState(PdpState.PASSIVE);
127
128         prov.createOrUpdateGroups(groups);
129
130         // should not have updated the state
131         assertEquals(PdpState.PASSIVE, group.getPdpGroupState());
132
133         assertSame(group, getGroupCreates().get(0));
134     }
135
136     @Test
137     public void testAddGroup_Invalid() throws Exception {
138         PdpGroups groups = loadPdpGroups("createGroups.json");
139         groups.getGroups().get(0).setPdpGroupState(PdpState.TERMINATED);
140
141         assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).isInstanceOf(PfModelException.class)
142                         .hasMessageContaining("pdpGroupState");
143
144         assertNoGroupAction();
145     }
146
147     @Test
148     public void testValidateGroupOnly_NullState() throws PfModelException {
149         PdpGroups groups = loadPdpGroups("createGroups.json");
150         groups.getGroups().get(0).setPdpGroupState(null);
151         prov.createOrUpdateGroups(groups);
152     }
153
154     @Test
155     public void testValidateGroupOnly_Active() throws PfModelException {
156         PdpGroups groups = loadPdpGroups("createGroups.json");
157         groups.getGroups().get(0).setPdpGroupState(PdpState.ACTIVE);
158         prov.createOrUpdateGroups(groups);
159     }
160
161     @Test
162     public void testValidateGroupOnly_Passive() throws PfModelException {
163         PdpGroups groups = loadPdpGroups("createGroups.json");
164         groups.getGroups().get(0).setPdpGroupState(PdpState.PASSIVE);
165         prov.createOrUpdateGroups(groups);
166     }
167
168     @Test
169     public void testValidateGroupOnly_Invalid() {
170         PdpGroups groups = loadPdpGroups("createGroups.json");
171         groups.getGroups().get(0).setPdpGroupState(PdpState.TERMINATED);
172
173         assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).isInstanceOf(PfModelException.class)
174                         .hasMessageContaining("pdpGroupState");
175     }
176
177     @Test
178     public void testUpdateGroup() throws Exception {
179         PdpGroups groups = loadPdpGroups("createGroups.json");
180
181         // DB group = new group
182         PdpGroup group = new PdpGroup(groups.getGroups().get(0));
183         when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
184
185         prov.createOrUpdateGroups(groups);
186
187         assertNoGroupAction();
188     }
189
190     @Test
191     public void testUpdateGroup_PropertiesChanged() throws Exception {
192         PdpGroups groups = loadPdpGroups("createGroups.json");
193
194         PdpGroup group = new PdpGroup(groups.getGroups().get(0));
195         group.setProperties(new TreeMap<>());
196
197         when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
198
199         assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).isInstanceOf(PfModelException.class)
200                         .hasMessageContaining("properties");
201
202         assertNoGroupAction();
203     }
204
205     @Test
206     public void testUpdateGroup_NewDescription() throws Exception {
207         PdpGroups groups = loadPdpGroups("createGroups.json");
208         PdpGroup newgrp = groups.getGroups().get(0);
209         PdpGroup group = new PdpGroup(newgrp);
210         group.setDescription("old description");
211         when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
212
213         prov.createOrUpdateGroups(groups);
214
215         assertGroupUpdateOnly(group);
216
217         assertEquals(group.getDescription(), "my description");
218         assertEquals(newgrp.toString(), group.toString());
219     }
220
221     @Test
222     public void testUpdateGroup_NewState() throws Exception {
223         PdpGroups groups = loadPdpGroups("createGroups.json");
224         PdpGroup newgrp = groups.getGroups().get(0);
225         PdpGroup group = new PdpGroup(newgrp);
226         group.setPdpGroupState(PdpState.TEST);
227         when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
228
229         prov.createOrUpdateGroups(groups);
230
231         assertGroupUpdateOnly(group);
232
233         assertEquals(PdpState.ACTIVE, group.getPdpGroupState());
234         assertEquals(newgrp.toString(), group.toString());
235     }
236
237     @Test
238     public void testUpdateGroup_UpdatedSubGroup() throws Exception {
239         PdpGroups groups = loadPdpGroups("createGroups.json");
240         PdpGroup newgrp = groups.getGroups().get(0);
241         PdpGroup group = new PdpGroup(newgrp);
242         when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
243
244         // something different in this subgroup
245         group.getPdpSubgroups().get(0).setDesiredInstanceCount(10);
246
247         prov.createOrUpdateGroups(groups);
248
249         assertEquals(newgrp.toString(), group.toString());
250         assertGroupUpdateOnly(group);
251     }
252
253     @Test
254     public void testUpdateGroup_MultipleChanges() throws Exception {
255         PdpGroups groups = loadPdpGroups("createGroups.json");
256         PdpGroup newgrp = groups.getGroups().get(0);
257         PdpGroup group = new PdpGroup(newgrp);
258         when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
259
260         PdpSubGroup subgrp = newgrp.getPdpSubgroups().get(0);
261         subgrp.setDesiredInstanceCount(30);
262         subgrp.getPolicies().add(new ToscaPolicyIdentifier(POLICY2_NAME, POLICY1_VERSION));
263         subgrp.getSupportedPolicyTypes().add(new ToscaPolicyTypeIdentifier("typeX.*", "9.8.7"));
264
265         when(dao.getFilteredPolicyList(any()))
266                         .thenReturn(loadPolicies("createGroupNewPolicy.json"))
267                         .thenReturn(loadPolicies("daoPolicyList.json"))
268                         .thenReturn(loadPolicies("createGroupNewPolicy.json"));
269
270         prov.createOrUpdateGroups(groups);
271
272         Collections.sort(newgrp.getPdpSubgroups().get(0).getPolicies());
273         Collections.sort(group.getPdpSubgroups().get(0).getPolicies());
274
275         assertEquals(newgrp.toString(), group.toString());
276
277         // this requires a PDP UPDATE message
278         assertGroupUpdate(group, subgrp);
279     }
280
281     @Test
282     public void testUpdateField_Unchanged() throws Exception {
283         PdpGroups groups = loadPdpGroups("createGroups.json");
284         PdpGroup newgrp = groups.getGroups().get(0);
285         PdpGroup group = new PdpGroup(newgrp);
286         when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
287
288         prov.createOrUpdateGroups(groups);
289
290         assertNoGroupAction();
291     }
292
293     @Test
294     public void testUpdateField_WasNull() throws Exception {
295         PdpGroups groups = loadPdpGroups("createGroups.json");
296         PdpGroup newgrp = groups.getGroups().get(0);
297         PdpGroup group = new PdpGroup(newgrp);
298         when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
299
300         group.setDescription(null);
301
302         prov.createOrUpdateGroups(groups);
303
304         assertEquals(newgrp.toString(), group.toString());
305         assertGroupUpdateOnly(group);
306     }
307
308     @Test
309     public void testUpdateField_NowNull() throws Exception {
310         PdpGroups groups = loadPdpGroups("createGroups.json");
311         PdpGroup newgrp = groups.getGroups().get(0);
312         PdpGroup group = new PdpGroup(newgrp);
313         when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
314
315         newgrp.setDescription(null);
316
317         prov.createOrUpdateGroups(groups);
318
319         assertEquals(newgrp.toString(), group.toString());
320         assertGroupUpdateOnly(group);
321     }
322
323     @Test
324     public void testUpdateField_Changed() throws Exception {
325         PdpGroups groups = loadPdpGroups("createGroups.json");
326         PdpGroup newgrp = groups.getGroups().get(0);
327         PdpGroup group = new PdpGroup(newgrp);
328         when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
329
330         newgrp.setDescription(group.getDescription() + "-changed");
331
332         prov.createOrUpdateGroups(groups);
333
334         assertEquals(newgrp.toString(), group.toString());
335         assertGroupUpdateOnly(group);
336     }
337
338     /**
339      * Tests addSubgroup() when the new subgroup has a wild-card policy type.
340      *
341      * @throws Exception if an error occurs
342      */
343     @Test
344     public void testAddSubGroupWildCardPolicyType() throws Exception {
345         when(dao.getFilteredPolicyList(any())).thenReturn(loadPolicies("daoPolicyListWildCard.json"));
346         when(dao.getPolicyTypeList("some.*", "2.3.4")).thenReturn(Collections.emptyList());
347
348         PdpGroups groups = loadPdpGroups("createGroupsWildCard.json");
349         PdpGroup group = loadPdpGroups("createGroups.json").getGroups().get(0);
350         when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
351
352         prov.createOrUpdateGroups(groups);
353
354         PdpGroup newgrp = groups.getGroups().get(0);
355
356         PdpSubGroup newsub = newgrp.getPdpSubgroups().get(1);
357         newsub.setCurrentInstanceCount(0);
358         newsub.setPdpInstances(new ArrayList<>(0));
359
360         assertEquals(newgrp.toString(), group.toString());
361     }
362
363     /**
364      * Tests addSubgroup() when the new subgroup has a wild-card policy type, but the
365      * policy doesn't have a matching type.
366      *
367      * @throws PfModelException if an error occurs
368      */
369     @Test
370     public void testAddSubGroupWildCardPolicyTypeUnmatched() throws PfModelException {
371         when(dao.getFilteredPolicyList(any())).thenReturn(loadPolicies("daoPolicyListWildCardUnmatched.json"));
372         when(dao.getPolicyTypeList("some.*", "2.3.4")).thenReturn(Collections.emptyList());
373
374         PdpGroups groups = loadPdpGroups("createGroupsWildCard.json");
375         PdpGroup group = loadPdpGroups("createGroups.json").getGroups().get(0);
376         when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
377
378         assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).isInstanceOf(PfModelException.class);
379     }
380
381     @Test
382     public void testAddSubGroup_ValidationPolicyTypeNotFound() throws Exception {
383         PdpGroups groups = loadPdpGroups("createGroupsNewSub.json");
384         PdpGroup group = loadPdpGroups("createGroups.json").getGroups().get(0);
385         when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
386
387         when(dao.getPolicyTypeList(any(), any())).thenReturn(Collections.emptyList());
388
389         assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).hasMessageContaining("unknown policy type");
390     }
391
392     @Test
393     public void testAddSubGroup_ValidationPolicyTypeDaoEx() throws Exception {
394         PdpGroups groups = loadPdpGroups("createGroupsNewSub.json");
395         PdpGroup group = loadPdpGroups("createGroups.json").getGroups().get(0);
396         when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
397
398         PfModelException exc = new PfModelException(Status.CONFLICT, EXPECTED_EXCEPTION);
399         when(dao.getPolicyTypeList(any(), any())).thenThrow(exc);
400
401         assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).isSameAs(exc);
402     }
403
404     @Test
405     public void testAddSubGroup_ValidationPolicyNotFound() throws Exception {
406         PdpGroups groups = loadPdpGroups("createGroupsNewSubNotFound.json");
407         PdpGroup group = loadPdpGroups("createGroups.json").getGroups().get(0);
408         when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
409
410         when(dao.getFilteredPolicyList(any())).thenReturn(Collections.emptyList());
411
412         assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).hasMessageContaining("unknown policy");
413     }
414
415     @Test
416     public void testAddSubGroup_ValidationPolicyDaoEx() throws Exception {
417         PdpGroups groups = loadPdpGroups("createGroupsNewSubNotFound.json");
418         PdpGroup group = loadPdpGroups("createGroups.json").getGroups().get(0);
419         when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
420
421         PfModelException exc = new PfModelException(Status.CONFLICT, EXPECTED_EXCEPTION);
422         when(dao.getFilteredPolicyList(any())).thenThrow(exc);
423
424         assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).isSameAs(exc);
425     }
426
427     @Test
428     public void testUpdateSubGroup_Invalid() throws Exception {
429         PdpGroups groups = loadPdpGroups("createGroups.json");
430         PdpGroup newgrp = groups.getGroups().get(0);
431         PdpGroup group = new PdpGroup(newgrp);
432         when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
433
434         // change properties
435         newgrp.getPdpSubgroups().get(0).setProperties(new TreeMap<>());
436
437         assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).isInstanceOf(PfModelException.class)
438                         .hasMessageContaining("properties");
439
440         assertNoGroupAction();
441     }
442
443     @Test
444     public void testUpdateSubGroup_SupportedPolicies() throws Exception {
445         PdpGroups groups = loadPdpGroups("createGroups.json");
446         PdpGroup newgrp = groups.getGroups().get(0);
447         PdpGroup group = new PdpGroup(newgrp);
448         when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
449
450         newgrp.getPdpSubgroups().get(0).getSupportedPolicyTypes()
451                         .add(new ToscaPolicyTypeIdentifier("typeX.*", "9.8.7"));
452
453         prov.createOrUpdateGroups(groups);
454
455         assertEquals(newgrp.toString(), group.toString());
456         assertGroupUpdateOnly(group);
457     }
458
459     @Test
460     public void testUpdateSubGroup_DesiredCount() throws Exception {
461         PdpGroups groups = loadPdpGroups("createGroups.json");
462         PdpGroup newgrp = groups.getGroups().get(0);
463         PdpGroup group = new PdpGroup(newgrp);
464         when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
465
466         newgrp.getPdpSubgroups().get(0).setDesiredInstanceCount(20);
467
468         prov.createOrUpdateGroups(groups);
469
470         assertEquals(newgrp.toString(), group.toString());
471         assertGroupUpdateOnly(group);
472     }
473
474     @Test
475     public void testUpdateSubGroup_Policies() throws Exception {
476         PdpGroups groups = loadPdpGroups("createGroupsDelPolicy.json");
477         PdpGroup newgrp = groups.getGroups().get(0);
478         PdpGroup group = new PdpGroup(newgrp);
479         when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
480
481         PdpSubGroup subgrp = newgrp.getPdpSubgroups().get(0);
482
483         // delete second policy
484         subgrp.setPolicies(subgrp.getPolicies().subList(0, 1));
485
486         // add new policy
487         ToscaPolicyIdentifier policyId2 = new ToscaPolicyIdentifier(POLICY2_NAME, POLICY1_VERSION);
488         subgrp.getPolicies().add(policyId2);
489
490         when(dao.getFilteredPolicyList(any())).thenReturn(loadPolicies("createGroupNewPolicy.json"))
491                         .thenReturn(loadPolicies("daoPolicyList.json"))
492                         .thenReturn(loadPolicies("daoPolicyListDelPolicy.json"))
493                         .thenReturn(loadPolicies("createGroupNewPolicy.json"));
494
495         prov.createOrUpdateGroups(groups);
496
497         Collections.sort(newgrp.getPdpSubgroups().get(0).getPolicies());
498         Collections.sort(group.getPdpSubgroups().get(0).getPolicies());
499
500         assertEquals(newgrp.toString(), group.toString());
501
502         // should have notified of added policy/PDPs
503         ArgumentCaptor<PolicyPdpNotificationData> captor = ArgumentCaptor.forClass(PolicyPdpNotificationData.class);
504         verify(notifier).addDeploymentData(captor.capture());
505         assertDeploymentData(captor, policyId2, "[pdpA]");
506
507         // should have notified of deleted policy/PDPs
508         captor = ArgumentCaptor.forClass(PolicyPdpNotificationData.class);
509         verify(notifier).addUndeploymentData(captor.capture());
510         assertDeploymentData(captor, new ToscaPolicyIdentifier("ToBeDeleted", POLICY1_VERSION), "[pdpA]");
511
512         // this requires a PDP UPDATE message
513         assertGroupUpdate(group, subgrp);
514     }
515
516     @Test
517     public void testUpdateSubGroup_Unchanged() throws Exception {
518         PdpGroups groups = loadPdpGroups("createGroups.json");
519         PdpGroup newgrp = groups.getGroups().get(0);
520         PdpGroup group = new PdpGroup(newgrp);
521         when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
522
523         prov.createOrUpdateGroups(groups);
524
525         Collections.sort(newgrp.getPdpSubgroups().get(0).getPolicies());
526         Collections.sort(group.getPdpSubgroups().get(0).getPolicies());
527
528         assertEquals(newgrp.toString(), group.toString());
529
530         // no notifications
531         verify(notifier, never()).addDeploymentData(any());
532         verify(notifier, never()).addUndeploymentData(any());
533
534         // no group updates
535         assertNoGroupAction();
536     }
537
538     @Test
539     public void testValidateSubGroup_PropertiesMismatch() throws Exception {
540         PdpGroups groups = loadPdpGroups("createGroups.json");
541         PdpGroup newgrp = groups.getGroups().get(0);
542         PdpGroup group = new PdpGroup(newgrp);
543         when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
544
545         newgrp.setProperties(new TreeMap<>());
546
547         assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).isInstanceOf(PfModelException.class)
548                         .hasMessageContaining("properties");
549
550         assertNoGroupAction();
551     }
552
553     @Test
554     public void testDeployPolicies() throws PfModelException {
555         prov.deployPolicies(loadEmptyRequest());
556     }
557
558     /**
559      * Tests deployPolicies() when the supported policy type uses a wild-card.
560      *
561      * @throws Exception if an error occurs
562      */
563     @Test
564     public void testDeployPoliciesWildCard() throws Exception {
565         when(dao.getFilteredPdpGroups(any())).thenReturn(loadGroups("deployPoliciesWildCard.json"));
566         when(dao.getFilteredPolicyList(any())).thenReturn(loadPolicies("daoPolicyListWildCard.json"));
567         when(dao.getPolicyTypeList(any(), any())).thenReturn(Collections.emptyList());
568
569         policy1.setName("policy.some");
570         policy1.setVersion(POLICY1_VERSION);
571         policy1.setType("some.type");
572         policy1.setTypeVersion("100.2.3");
573
574         PdpDeployPolicies depreq = loadRequest();
575         depreq.getPolicies().get(0).setName("policy.some");
576
577         prov.deployPolicies(depreq);
578
579         assertGroup(getGroupUpdates(), GROUP1_NAME);
580
581         List<PdpUpdate> requests = getUpdateRequests(1);
582         assertUpdate(requests, GROUP1_NAME, PDP2_TYPE, PDP2);
583
584         // should have notified of added policy/PDPs
585         ArgumentCaptor<PolicyPdpNotificationData> captor = ArgumentCaptor.forClass(PolicyPdpNotificationData.class);
586         verify(notifier).addDeploymentData(captor.capture());
587         assertDeploymentData(captor, policy1.getIdentifier(), "[pdpB]");
588
589         // no undeployment notifications
590         verify(notifier, never()).addUndeploymentData(any());
591     }
592
593     @Test
594     public void testDeploySimplePolicies() throws Exception {
595         prov.deployPolicies(loadEmptyRequest());
596     }
597
598     @Test
599     public void testDeploySimplePolicies_DaoEx() throws Exception {
600         PfModelException exc = new PfModelException(Status.BAD_REQUEST, EXPECTED_EXCEPTION);
601         when(dao.getFilteredPdpGroups(any())).thenThrow(exc);
602
603         assertThatThrownBy(() -> prov.deployPolicies(loadRequest())).isSameAs(exc);
604     }
605
606     @Test
607     public void testDeploySimplePolicies_DaoPfRtEx() throws Exception {
608         PfModelRuntimeException exc = new PfModelRuntimeException(Status.BAD_REQUEST, EXPECTED_EXCEPTION);
609         when(dao.getFilteredPdpGroups(any())).thenThrow(exc);
610
611         assertThatThrownBy(() -> prov.deployPolicies(loadRequest())).isSameAs(exc);
612     }
613
614     @Test
615     public void testDeploySimplePolicies_RuntimeEx() throws Exception {
616         RuntimeException exc = new RuntimeException(EXPECTED_EXCEPTION);
617         when(dao.getFilteredPolicyList(any())).thenThrow(exc);
618
619         assertThatThrownBy(() -> prov.deployPolicies(loadRequest())).isInstanceOf(PfModelException.class).hasCause(exc);
620     }
621
622     @Test
623     public void testDeploySimplePolicies_NoGroups() throws Exception {
624         when(dao.getFilteredPdpGroups(any())).thenReturn(loadGroups("emptyGroups.json"));
625
626         assertThatThrownBy(() -> prov.deployPolicies(loadRequest())).isInstanceOf(PfModelException.class)
627                         .hasMessage("policy not supported by any PDP group: policyA 1.2.3");
628     }
629
630     @Test
631     public void testMakeUpdater() throws Exception {
632         /*
633          * Each subgroup has a different PDP type and name.
634          *
635          * Type is not supported by the first subgroup.
636          *
637          * Second subgroup matches.
638          *
639          * Third subgroup already contains the policy.
640          *
641          * Last subgroup matches.
642          */
643
644         when(dao.getFilteredPdpGroups(any())).thenReturn(loadGroups("upgradeGroupDao.json"));
645
646         prov.deployPolicies(loadRequest());
647
648         assertGroup(getGroupUpdates(), GROUP1_NAME);
649
650         List<PdpUpdate> requests = getUpdateRequests(2);
651         assertUpdate(requests, GROUP1_NAME, PDP2_TYPE, PDP2);
652         assertUpdate(requests, GROUP1_NAME, PDP4_TYPE, PDP4);
653
654         // should have notified of added policy/PDPs
655         ArgumentCaptor<PolicyPdpNotificationData> captor = ArgumentCaptor.forClass(PolicyPdpNotificationData.class);
656         verify(notifier).addDeploymentData(captor.capture());
657         assertDeploymentData(captor, policy1.getIdentifier(), "[pdpB, pdpD]");
658
659         // no undeployment notifications
660         verify(notifier, never()).addUndeploymentData(any());
661     }
662
663     @Test
664     public void testMakeUpdater_PolicyVersionMismatch() throws Exception {
665
666         // subgroup has a different version of the Policy
667         when(dao.getFilteredPdpGroups(any())).thenReturn(loadGroups("upgradeGroupDao_DiffVers.json"));
668
669         assertThatThrownBy(() -> prov.deployPolicies(loadRequest())).isInstanceOf(PfModelRuntimeException.class)
670                         .hasMessageContaining("pdpTypeC").hasMessageContaining("different version already deployed");
671
672         verify(dao, never()).createPdpGroups(any());
673         verify(dao, never()).updatePdpGroups(any());
674         verify(reqmap, never()).addRequest(any(PdpUpdate.class));
675     }
676
677     @Test
678     public void testMakeUpdater_NoPdps() throws Exception {
679
680         // subgroup has no PDPs
681         when(dao.getFilteredPdpGroups(any())).thenReturn(loadGroups("upgradeGroup_NoPdpsDao.json"));
682
683         assertThatThrownBy(() -> prov.deployPolicies(loadRequest())).isInstanceOf(PfModelRuntimeException.class)
684                         .hasMessage("group " + GROUP1_NAME + " subgroup " + PDP1_TYPE + " has no active PDPs");
685
686         verify(dao, never()).createPdpGroups(any());
687         verify(dao, never()).updatePdpGroups(any());
688         verify(reqmap, never()).addRequest(any(PdpUpdate.class));
689     }
690
691
692     protected void assertUpdate(List<PdpUpdate> updates, String groupName, String pdpType, String pdpName) {
693
694         PdpUpdate update = updates.remove(0);
695
696         assertEquals(groupName, update.getPdpGroup());
697         assertEquals(pdpType, update.getPdpSubgroup());
698         assertEquals(pdpName, update.getName());
699         assertTrue(update.getPolicies().contains(policy1));
700     }
701
702     private void assertNoGroupAction() throws Exception {
703         verify(dao, never()).createPdpGroups(any());
704         verify(dao, never()).updatePdpGroups(any());
705         verify(reqmap, never()).addRequest(any(), any());
706     }
707
708     private void assertGroupUpdate(PdpGroup group, PdpSubGroup subgrp) throws Exception {
709         verify(dao, never()).createPdpGroups(any());
710
711         assertEquals(0, getStateChangeRequests(1).size());
712
713         List<PdpUpdate> pdpUpdates = getUpdateRequests(1);
714         assertEquals(1, pdpUpdates.size());
715
716         PdpUpdate pdpUpdate = pdpUpdates.get(0);
717         assertEquals("pdpA", pdpUpdate.getName());
718         assertEquals(group.getName(), pdpUpdate.getPdpGroup());
719
720         assertEquals(subgrp.getPdpType(), pdpUpdate.getPdpSubgroup());
721
722         List<ToscaPolicyIdentifier> pdpPolicies =
723                         pdpUpdate.getPolicies().stream().map(ToscaPolicy::getIdentifier).collect(Collectors.toList());
724         Collections.sort(pdpPolicies);
725
726         assertEquals(subgrp.getPolicies().toString(), pdpPolicies.toString());
727
728         List<PdpGroup> updates = getGroupUpdates();
729         assertEquals(Arrays.asList(group), updates);
730     }
731
732     private void assertGroupUpdateOnly(PdpGroup group) throws Exception {
733         verify(dao, never()).createPdpGroups(any());
734         verify(reqmap, never()).addRequest(any(), any());
735
736         List<PdpGroup> updates = getGroupUpdates();
737         assertEquals(Arrays.asList(group), updates);
738     }
739
740     private void assertDeploymentData(ArgumentCaptor<PolicyPdpNotificationData> captor, ToscaPolicyIdentifier policyId,
741                     String expectedPdps) {
742         PolicyPdpNotificationData data = captor.getValue();
743         assertEquals(policyId, data.getPolicyId());
744         assertEquals(policy1.getTypeIdentifier(), data.getPolicyType());
745         assertEquals(expectedPdps, new TreeSet<>(data.getPdps()).toString());
746     }
747
748     /**
749      * Loads a standard request.
750      *
751      * @return a standard request
752      */
753     protected PdpDeployPolicies loadRequest() {
754         return loadRequest("request.json");
755     }
756
757     /**
758      * Loads a request from a JSON file.
759      *
760      * @param fileName name of the file from which to load
761      * @return the request that was loaded
762      */
763     protected PdpDeployPolicies loadRequest(String fileName) {
764         return loadFile(fileName, PdpDeployPolicies.class);
765     }
766
767     /**
768      * Loads an empty request.
769      *
770      * @return an empty request
771      */
772     protected PdpDeployPolicies loadEmptyRequest() {
773         return loadRequest("emptyRequest.json");
774     }
775 }