2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights reserved.
6 * Modifications Copyright (C) 2021 Nordix Foundation.
7 * Modifications Copyright (C) 2022 Bell Canada. All rights reserved.
8 * ================================================================================
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
23 package org.onap.policy.pap.main.rest;
25 import static org.assertj.core.api.Assertions.assertThat;
26 import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
27 import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
28 import static org.assertj.core.api.Assertions.assertThatThrownBy;
29 import static org.junit.Assert.assertEquals;
30 import static org.junit.Assert.assertFalse;
31 import static org.junit.Assert.assertNull;
32 import static org.junit.Assert.assertSame;
33 import static org.junit.Assert.assertTrue;
34 import static org.mockito.ArgumentMatchers.any;
35 import static org.mockito.ArgumentMatchers.anyBoolean;
36 import static org.mockito.Mockito.mock;
37 import static org.mockito.Mockito.never;
38 import static org.mockito.Mockito.times;
39 import static org.mockito.Mockito.verify;
40 import static org.mockito.Mockito.when;
42 import java.util.ArrayList;
43 import java.util.Arrays;
44 import java.util.Collection;
45 import java.util.Collections;
46 import java.util.Comparator;
47 import java.util.Iterator;
48 import java.util.List;
49 import javax.ws.rs.core.Response.Status;
50 import org.apache.commons.lang3.tuple.Pair;
51 import org.junit.Before;
52 import org.junit.Test;
53 import org.mockito.ArgumentCaptor;
54 import org.onap.policy.models.base.PfModelException;
55 import org.onap.policy.models.pap.concepts.PolicyNotification;
56 import org.onap.policy.models.pdp.concepts.PdpGroup;
57 import org.onap.policy.models.pdp.concepts.PdpStateChange;
58 import org.onap.policy.models.pdp.concepts.PdpUpdate;
59 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
60 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifierOptVersion;
61 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
62 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyType;
63 import org.onap.policy.models.tosca.authorative.concepts.ToscaTypedEntityFilter;
64 import org.onap.policy.pap.main.notification.DeploymentStatus;
65 import org.onap.policy.pap.main.service.PolicyStatusService;
67 public class TestSessionData extends ProviderSuper {
68 private static final String GROUP_NAME = "groupA";
69 private static final String PDP_TYPE = "MySubGroup";
70 private static final String PDP1 = "pdp_1";
71 private static final String PDP2 = "pdp_2";
72 private static final String PDP3 = "pdp_3";
73 private static final String POLICY_VERSION_PREFIX = "1.2.";
74 private static final String POLICY_NAME = "myPolicy";
75 private static final String POLICY_VERSION = POLICY_VERSION_PREFIX + "3";
76 private static final String POLICY_TYPE = "myType";
77 private static final String POLICY_TYPE_VERSION = "10.20.30";
78 private static final String EXPECTED_EXCEPTION = "expected exception";
80 private SessionData session;
81 private ToscaConceptIdentifierOptVersion ident;
82 private ToscaConceptIdentifier type;
83 private ToscaConceptIdentifier type2;
84 private PdpGroup group1;
85 private PdpGroup group2;
88 * Initializes mocks and a session.
90 * @throws Exception if an error occurs
94 public void setUp() throws Exception {
97 ident = new ToscaConceptIdentifierOptVersion(POLICY_NAME, POLICY_VERSION);
98 type = new ToscaConceptIdentifier(POLICY_TYPE, POLICY_TYPE_VERSION);
99 type2 = new ToscaConceptIdentifier(POLICY_TYPE, POLICY_TYPE_VERSION + "0");
100 group1 = loadGroup("group1.json");
101 group2 = loadGroup("group2.json");
103 session = new SessionData(DEFAULT_USER, toscaService, pdpGroupService, policyStatusService, policyAuditService);
107 public void testGetPolicyType() throws Exception {
108 ToscaPolicyType policy1 = makePolicyType(POLICY_TYPE, POLICY_TYPE_VERSION);
109 when(toscaService.getPolicyTypeList(POLICY_TYPE, POLICY_TYPE_VERSION)).thenReturn(Arrays.asList(policy1));
111 assertSame(policy1, session.getPolicyType(type));
113 // retrieve a second time - should use cache
114 assertSame(policy1, session.getPolicyType(type));
118 public void testGetPolicyType_NotFound() throws Exception {
119 when(toscaService.getPolicyTypeList(any(), any())).thenReturn(Collections.emptyList());
121 assertNull(session.getPolicyType(type));
125 public void testGetPolicyType_DaoEx() throws Exception {
126 PfModelException ex = new PfModelException(Status.INTERNAL_SERVER_ERROR, EXPECTED_EXCEPTION);
127 when(toscaService.getPolicyTypeList(POLICY_TYPE, POLICY_TYPE_VERSION)).thenThrow(ex);
129 assertThatThrownBy(() -> session.getPolicyType(type)).isSameAs(ex);
133 public void testGetPolicy_NullVersion() throws Exception {
134 ToscaPolicy policy1 = makePolicy(POLICY_NAME, POLICY_VERSION);
135 when(toscaService.getFilteredPolicyList(any())).thenReturn(Arrays.asList(policy1));
137 ident.setVersion(null);
138 assertSame(policy1, session.getPolicy(ident));
140 ToscaTypedEntityFilter<ToscaPolicy> filter = getPolicyFilter();
141 assertEquals(POLICY_NAME, filter.getName());
142 assertEquals(ToscaTypedEntityFilter.LATEST_VERSION, filter.getVersion());
143 assertEquals(null, filter.getVersionPrefix());
145 // retrieve a second time using full version - should use cache
146 assertSame(policy1, session.getPolicy(new ToscaConceptIdentifierOptVersion(policy1.getIdentifier())));
147 verify(toscaService).getFilteredPolicyList(any());
151 public void testGetPolicy_MajorVersion() throws Exception {
152 ToscaPolicy policy1 = makePolicy(POLICY_NAME, POLICY_VERSION);
153 when(toscaService.getFilteredPolicyList(any())).thenReturn(Arrays.asList(policy1));
155 ident.setVersion("1");
156 assertSame(policy1, session.getPolicy(ident));
158 ToscaTypedEntityFilter<ToscaPolicy> filter = getPolicyFilter();
159 assertEquals(POLICY_NAME, filter.getName());
160 assertEquals(ToscaTypedEntityFilter.LATEST_VERSION, filter.getVersion());
161 assertEquals("1.", filter.getVersionPrefix());
163 // retrieve a second time using full version - should use cache
164 assertSame(policy1, session.getPolicy(new ToscaConceptIdentifierOptVersion(policy1.getIdentifier())));
165 verify(toscaService).getFilteredPolicyList(any());
169 public void testGetPolicy_MajorMinorVersion() throws Exception {
170 ToscaPolicy policy1 = makePolicy(POLICY_NAME, POLICY_VERSION);
171 when(toscaService.getFilteredPolicyList(any())).thenReturn(Arrays.asList(policy1));
173 ident.setVersion(POLICY_VERSION);
174 assertSame(policy1, session.getPolicy(ident));
176 ToscaTypedEntityFilter<ToscaPolicy> filter = getPolicyFilter();
177 assertEquals(POLICY_NAME, filter.getName());
178 assertEquals(POLICY_VERSION, filter.getVersion());
179 assertEquals(null, filter.getVersionPrefix());
181 // retrieve a second time using full version - should use cache
182 assertSame(policy1, session.getPolicy(new ToscaConceptIdentifierOptVersion(policy1.getIdentifier())));
183 verify(toscaService).getFilteredPolicyList(any());
187 public void testGetPolicy_NotFound() throws Exception {
188 when(toscaService.getFilteredPolicyList(any())).thenReturn(Collections.emptyList());
190 assertNull(session.getPolicy(ident));
194 public void testGetPolicy_DaoEx() throws Exception {
195 PfModelException ex = new PfModelException(Status.INTERNAL_SERVER_ERROR, EXPECTED_EXCEPTION);
196 when(toscaService.getFilteredPolicyList(any())).thenThrow(ex);
198 assertThatThrownBy(() -> session.getPolicy(ident)).isSameAs(ex);
202 public void testIsVersionPrefix() {
203 assertTrue(SessionData.isVersionPrefix("1"));
204 assertTrue(SessionData.isVersionPrefix("12"));
205 assertTrue(SessionData.isVersionPrefix("1.2"));
206 assertTrue(SessionData.isVersionPrefix("1.23"));
208 assertFalse(SessionData.isVersionPrefix("1."));
209 assertFalse(SessionData.isVersionPrefix("1.2."));
210 assertFalse(SessionData.isVersionPrefix("1.2.3"));
211 assertFalse(SessionData.isVersionPrefix("1.2.3."));
212 assertFalse(SessionData.isVersionPrefix("1.2.3.4"));
216 public void testAddRequests_testGetPdpStateChanges_testGetPdpUpdates() {
217 // pre-load with a update and state-change for other PDPs
218 PdpUpdate update2 = makeUpdate(PDP2);
219 session.addUpdate(update2);
221 PdpStateChange change3 = makeStateChange(PDP3);
222 session.addStateChange(change3);
225 PdpUpdate update = makeUpdate(PDP1);
226 PdpStateChange change = makeStateChange(PDP1);
227 session.addRequests(update, change);
228 verifyRequests(update, update2, change, change3);
231 * repeat with a new pair
233 update = makeUpdate(PDP1);
234 change = makeStateChange(PDP1);
235 session.addRequests(update, change);
236 verifyRequests(update, update2, change, change3);
238 // just make an update this time
239 update = makeUpdate(PDP1);
240 session.addUpdate(update);
241 verifyRequests(update, update2, change, change3);
244 private void verifyRequests(PdpUpdate update, PdpUpdate update2, PdpStateChange change, PdpStateChange change3) {
245 List<Pair<PdpUpdate, PdpStateChange>> requests = sort(session.getPdpRequests(), this::compare);
246 assertEquals(3, requests.size());
248 System.out.println(requests);
249 System.out.println(update);
251 Iterator<Pair<PdpUpdate, PdpStateChange>> reqiter = requests.iterator();
252 Pair<PdpUpdate, PdpStateChange> pair = reqiter.next();
253 assertSame(update, pair.getLeft());
254 assertSame(change, pair.getRight());
256 pair = reqiter.next();
257 assertSame(update2, pair.getLeft());
258 assertSame(null, pair.getRight());
260 pair = reqiter.next();
261 assertSame(null, pair.getLeft());
262 assertSame(change3, pair.getRight());
264 // verify individual lists
265 List<PdpUpdate> updates = Arrays.asList(update, update2);
266 assertEquals(sort(updates, this::compare), sort(session.getPdpUpdates(), this::compare));
268 List<PdpStateChange> changes = Arrays.asList(change, change3);
269 assertEquals(sort(changes, this::compare), sort(session.getPdpStateChanges(), this::compare));
273 public void testAddRequests_MismatchedNames() {
274 PdpUpdate update = makeUpdate(PDP1);
275 PdpStateChange change = makeStateChange(PDP2);
276 assertThatIllegalArgumentException().isThrownBy(() -> session.addRequests(update, change))
277 .withMessage("PDP name mismatch pdp_1, pdp_2");
281 public void testAddUpdate_testGetPdpUpdates() {
282 // several different updates, but one duplicate
283 PdpUpdate update1 = makeUpdate(PDP1);
284 session.addUpdate(update1);
286 PdpUpdate update2 = makeUpdate(PDP2);
287 session.addUpdate(update2);
289 PdpUpdate update3 = makeUpdate(PDP3);
290 session.addUpdate(update3);
292 List<PdpUpdate> lst = sort(getUpdateRequests(), this::compare);
293 assertEquals(Arrays.asList(update1, update2, update3).toString(), lst.toString());
296 update2 = makeUpdate(PDP2);
297 session.addUpdate(update2);
299 lst = sort(getUpdateRequests(), this::compare);
300 assertEquals(Arrays.asList(update1, update2, update3).toString(), lst.toString());
304 public void testAddStateChange_testGetPdpStateChanges() {
305 // several different changes, but one duplicate
306 PdpStateChange change1 = makeStateChange(PDP1);
307 session.addStateChange(change1);
309 PdpStateChange change2 = makeStateChange(PDP2);
310 session.addStateChange(change2);
312 PdpStateChange change3 = makeStateChange(PDP3);
313 session.addStateChange(change3);
315 List<PdpStateChange> lst = sort(getStateChangeRequests(), this::compare);
316 assertEquals(Arrays.asList(change1, change2, change3).toString(), lst.toString());
319 change2 = makeStateChange(PDP2);
320 session.addStateChange(change2);
322 lst = sort(getStateChangeRequests(), this::compare);
323 assertEquals(Arrays.asList(change1, change2, change3).toString(), lst.toString());
326 private ToscaPolicyType makePolicyType(String name, String version) {
327 ToscaPolicyType type = new ToscaPolicyType();
330 type.setVersion(version);
335 private ToscaPolicy makePolicy(String name, String version) {
336 ToscaPolicy policy = new ToscaPolicy();
338 policy.setName(name);
339 policy.setVersion(version);
345 public void testCreate() throws Exception {
346 assertTrue(session.isUnchanged());
348 session.create(group1);
349 assertSame(group1, session.getGroup(group1.getName()));
350 assertFalse(session.isUnchanged());
353 session.create(group2);
354 assertSame(group1, session.getGroup(group1.getName()));
355 assertSame(group2, session.getGroup(group2.getName()));
356 assertFalse(session.isUnchanged());
359 assertThatIllegalStateException().isThrownBy(() -> session.create(group1))
360 .withMessage("group already cached: groupA");
364 public void testUpdate() throws Exception {
365 assertTrue(session.isUnchanged());
367 // force the groups into the cache
368 when(pdpGroupService.getFilteredPdpGroups(any())).thenReturn(Arrays.asList(group1, group2));
369 session.getActivePdpGroupsByPolicyType(type);
374 when(pdpGroupService.getFilteredPdpGroups(any())).thenReturn(Arrays.asList(group1));
375 PdpGroup newgrp = new PdpGroup(group1);
376 session.update(newgrp);
377 assertFalse(session.isUnchanged());
380 newgrp = new PdpGroup(group1);
381 session.update(newgrp);
382 assertFalse(session.isUnchanged());
387 when(pdpGroupService.getFilteredPdpGroups(any())).thenReturn(Arrays.asList(group2));
388 newgrp = new PdpGroup(group2);
389 session.update(newgrp);
390 assertFalse(session.isUnchanged());
393 newgrp = new PdpGroup(group2);
394 session.update(newgrp);
395 assertFalse(session.isUnchanged());
399 public void testUpdate_NotInCache() throws Exception {
400 when(pdpGroupService.getFilteredPdpGroups(any())).thenReturn(Arrays.asList(group1));
402 assertThatIllegalStateException().isThrownBy(() -> session.update(new PdpGroup(group1)))
403 .withMessage("group not cached: groupA");
407 public void testGetGroup() throws Exception {
408 when(pdpGroupService.getPdpGroups(GROUP_NAME)).thenReturn(Arrays.asList(group1));
410 assertSame(group1, session.getGroup(GROUP_NAME));
411 verify(pdpGroupService).getPdpGroups(any(String.class));
414 assertSame(group1, session.getGroup(GROUP_NAME));
416 // should not access dao again
417 verify(pdpGroupService, times(1)).getPdpGroups(any(String.class));
421 public void testGetGroup_NotFound() throws Exception {
422 when(pdpGroupService.getPdpGroups(GROUP_NAME)).thenReturn(Collections.emptyList());
424 assertNull(session.getGroup(GROUP_NAME));
425 verify(pdpGroupService).getPdpGroups(any(String.class));
428 assertNull(session.getGroup(GROUP_NAME));
430 // SHOULD access dao again
431 verify(pdpGroupService, times(2)).getPdpGroups(GROUP_NAME);
434 when(pdpGroupService.getPdpGroups(GROUP_NAME)).thenReturn(Arrays.asList(group1));
435 assertSame(group1, session.getGroup(GROUP_NAME));
436 verify(pdpGroupService, times(3)).getPdpGroups(GROUP_NAME);
440 public void testGetActivePdpGroupsByPolicyType() throws Exception {
441 List<PdpGroup> groups = Arrays.asList(group1, group2);
442 when(pdpGroupService.getFilteredPdpGroups(any())).thenReturn(groups);
445 assertEquals(groups, session.getActivePdpGroupsByPolicyType(type));
446 assertEquals(groups, session.getActivePdpGroupsByPolicyType(type));
447 assertEquals(groups, session.getActivePdpGroupsByPolicyType(type));
449 // only invoked once - should have used the cache for the rest
450 verify(pdpGroupService, times(1)).getFilteredPdpGroups(any());
454 public void testAddGroup() throws Exception {
455 List<PdpGroup> groups = Arrays.asList(group1, group2);
456 when(pdpGroupService.getFilteredPdpGroups(any())).thenReturn(groups);
458 // query by each type
459 assertEquals(groups, session.getActivePdpGroupsByPolicyType(type));
460 assertEquals(groups, session.getActivePdpGroupsByPolicyType(type2));
462 // invoked once for each type
463 verify(pdpGroupService, times(2)).getFilteredPdpGroups(any());
465 // repeat - should be no more invocations
466 assertEquals(groups, session.getActivePdpGroupsByPolicyType(type));
467 assertEquals(groups, session.getActivePdpGroupsByPolicyType(type2));
468 verify(pdpGroupService, times(2)).getFilteredPdpGroups(any());
472 public void testUpdateDb() throws Exception {
473 // force the groups into the cache
474 PdpGroup group3 = loadGroup("group3.json");
475 when(pdpGroupService.getFilteredPdpGroups(any())).thenReturn(Arrays.asList(group1, group2, group3));
476 session.getActivePdpGroupsByPolicyType(type);
478 // create groups 4 & 5
479 PdpGroup group4 = loadGroup("group4.json");
480 session.create(group4);
482 PdpGroup group5 = loadGroup("group5.json");
483 session.create(group5);
486 when(pdpGroupService.getFilteredPdpGroups(any())).thenReturn(Arrays.asList(group1));
487 PdpGroup newgrp1 = new PdpGroup(group1);
488 session.update(newgrp1);
491 newgrp1 = new PdpGroup(newgrp1);
492 session.update(newgrp1);
495 when(pdpGroupService.getFilteredPdpGroups(any())).thenReturn(Arrays.asList(group3));
496 PdpGroup newgrp3 = new PdpGroup(group3);
497 session.update(newgrp3);
500 when(pdpGroupService.getFilteredPdpGroups(any())).thenReturn(Arrays.asList(group5));
501 PdpGroup newgrp5 = new PdpGroup(group5);
502 session.update(newgrp5);
504 // push the changes to the DB
505 PolicyNotification notif = new PolicyNotification();
506 session.updateDb(notif);
507 assertThat(notif.getAdded()).isEmpty();
509 // expect one create for groups 4 & 5 (group5 replaced by newgrp5)
510 List<PdpGroup> creates = getGroupCreates();
511 assertEquals(2, creates.size());
512 assertSame(group4, creates.get(0));
513 assertSame(newgrp5, creates.get(1));
515 // expect one update for groups 1 & 3
516 List<PdpGroup> updates = getGroupUpdates();
517 assertEquals(2, updates.size());
518 assertSame(newgrp1, updates.get(0));
519 assertSame(newgrp3, updates.get(1));
523 public void testUpdateDb_Empty() throws Exception {
524 // force data into the cache
525 when(pdpGroupService.getFilteredPdpGroups(any())).thenReturn(Arrays.asList(group1, group2));
526 session.getActivePdpGroupsByPolicyType(type);
528 PolicyNotification notif = new PolicyNotification();
529 session.updateDb(notif);
530 assertThat(notif.getAdded()).isEmpty();
532 verify(pdpGroupService, never()).createPdpGroups(any());
533 verify(pdpGroupService, never()).updatePdpGroups(any());
537 public void testDeleteGroupFromDb() throws Exception {
538 session.deleteGroupFromDb(group1);
540 verify(pdpGroupService).deletePdpGroup(group1.getName());
544 public void testTrackDeploy() throws PfModelException {
549 public void testTrackUndeploy() throws PfModelException {
553 protected void testTrack(boolean deploy) throws PfModelException {
555 DeploymentStatus status = mock(DeploymentStatus.class);
558 new SessionData(DEFAULT_USER, toscaService, pdpGroupService, policyStatusService, policyAuditService) {
560 protected DeploymentStatus makeDeploymentStatus(PolicyStatusService policyStatusService) {
565 ToscaPolicy policy = makePolicy(POLICY_NAME, POLICY_VERSION);
566 policy.setType(POLICY_TYPE);
567 policy.setTypeVersion(POLICY_TYPE_VERSION);
569 when(toscaService.getFilteredPolicyList(any())).thenReturn(Arrays.asList(policy));
571 ToscaConceptIdentifier policyId = new ToscaConceptIdentifier(POLICY_NAME, POLICY_VERSION);
572 List<String> pdps = Arrays.asList(PDP1, PDP2);
574 ToscaPolicy testPolicy = session.getPolicy(new ToscaConceptIdentifierOptVersion(policyId));
577 session.trackDeploy(testPolicy, pdps, GROUP_NAME, PDP_TYPE);
578 assertThat(session.getPoliciesToBeDeployed()).contains(testPolicy);
580 session.trackUndeploy(policyId, pdps, GROUP_NAME, PDP_TYPE);
581 assertThat(session.getPoliciesToBeUndeployed()).contains(policyId);
584 // should be called just once
585 verify(status).deleteDeployment(any(), anyBoolean());
586 verify(status, times(1)).deleteDeployment(policyId, !deploy);
588 // should be called for each PDP
589 verify(status, times(2)).deploy(any(), any(), any(), any(), any(), anyBoolean());
590 verify(status).deploy(PDP1, policyId, policy.getTypeIdentifier(), GROUP_NAME, PDP_TYPE, deploy);
591 verify(status).deploy(PDP2, policyId, policy.getTypeIdentifier(), GROUP_NAME, PDP_TYPE, deploy);
594 private PdpUpdate makeUpdate(String pdpName) {
595 PdpUpdate update = new PdpUpdate();
597 update.setName(pdpName);
602 private PdpStateChange makeStateChange(String pdpName) {
603 PdpStateChange change = new PdpStateChange();
605 change.setName(pdpName);
610 private ToscaTypedEntityFilter<ToscaPolicy> getPolicyFilter() throws Exception {
611 @SuppressWarnings("unchecked")
612 ArgumentCaptor<ToscaTypedEntityFilter<ToscaPolicy>> captor =
613 ArgumentCaptor.forClass(ToscaTypedEntityFilter.class);
614 verify(toscaService).getFilteredPolicyList(captor.capture());
616 return captor.getValue();
619 private List<PdpUpdate> getUpdateRequests() {
620 return session.getPdpUpdates();
623 private List<PdpStateChange> getStateChangeRequests() {
624 return session.getPdpStateChanges();
627 private <T> List<T> sort(Collection<T> collection, Comparator<T> comparator) {
628 List<T> lst = new ArrayList<>(collection);
629 Collections.sort(lst, comparator);
634 private int compare(Pair<PdpUpdate, PdpStateChange> left, Pair<PdpUpdate, PdpStateChange> right) {
635 return getName(left).compareTo(getName(right));
638 private int compare(PdpUpdate left, PdpUpdate right) {
639 return left.getName().compareTo(right.getName());
642 private int compare(PdpStateChange left, PdpStateChange right) {
643 return left.getName().compareTo(right.getName());
646 private String getName(Pair<PdpUpdate, PdpStateChange> pair) {
647 return (pair.getKey() != null ? pair.getKey().getName() : pair.getValue().getName());