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