Support Policy updates between PAP and PDPs
[policy/pap.git] / main / src / test / java / org / onap / policy / pap / main / comm / PdpHeartbeatListenerTest.java
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2019-2021 Nordix Foundation.
4  *  Modifications Copyright (C) 2020 AT&T Intellectual Property.
5  * ================================================================================
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * SPDX-License-Identifier: Apache-2.0
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.policy.pap.main.comm;
23
24 import static org.assertj.core.api.Assertions.assertThat;
25 import static org.junit.Assert.assertEquals;
26 import static org.junit.Assert.assertSame;
27
28 import java.text.ParseException;
29 import java.text.SimpleDateFormat;
30 import java.time.Instant;
31 import java.util.ArrayList;
32 import java.util.Arrays;
33 import java.util.Date;
34 import java.util.List;
35 import java.util.stream.Collectors;
36 import org.junit.Test;
37 import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure;
38 import org.onap.policy.common.utils.coder.CoderException;
39 import org.onap.policy.models.base.PfModelException;
40 import org.onap.policy.models.pdp.concepts.PdpGroup;
41 import org.onap.policy.models.pdp.concepts.PdpStatistics;
42 import org.onap.policy.models.pdp.concepts.PdpStatus;
43 import org.onap.policy.models.pdp.concepts.PdpSubGroup;
44 import org.onap.policy.models.pdp.concepts.PdpUpdate;
45 import org.onap.policy.models.pdp.enums.PdpHealthStatus;
46 import org.onap.policy.models.pdp.enums.PdpState;
47 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
48 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
49 import org.onap.policy.pap.main.parameters.CommonTestData;
50 import org.onap.policy.pap.main.parameters.PdpParameters;
51 import org.onap.policy.pap.main.rest.e2e.End2EndBase;
52
53 /**
54  * Class to perform unit test of {@link PdpHeartbeatListener}.
55  *
56  * @author Ram Krishna Verma (ram.krishna.verma@est.tech)
57  */
58 public class PdpHeartbeatListenerTest extends End2EndBase {
59
60     private static final String POLICY_VERSION = "1.0.0";
61     private static final String POLICY_NAME = "onap.policies.controlloop.operational.common.apex.SampleDomain";
62     private static final String APEX_TYPE = "apex";
63     private static final String DEFAULT_GROUP = "defaultGroup";
64     private static final String PDP_NAME = "pdp_1";
65     private static final CommInfrastructure INFRA = CommInfrastructure.NOOP;
66     private static final String TOPIC = "my-topic";
67
68     private Instant timeStamp;
69     private PdpHeartbeatListener pdpHeartbeatListener;
70
71     @Test
72     public void testPdpHeartbeatListener() throws CoderException, PfModelException {
73         addGroups("PdpGroups.json");
74         pdpHeartbeatListener = new PdpHeartbeatListener(new PdpParameters());
75
76         // Testing pdp registration success case
77         final PdpStatus status1 = new PdpStatus();
78         status1.setName(PDP_NAME);
79         status1.setState(PdpState.ACTIVE);
80         status1.setPdpGroup(DEFAULT_GROUP);
81         status1.setPdpType(APEX_TYPE);
82         status1.setHealthy(PdpHealthStatus.HEALTHY);
83         final List<ToscaConceptIdentifier> idents1 =
84                 Arrays.asList(new ToscaConceptIdentifier(POLICY_NAME, POLICY_VERSION));
85         status1.setPolicies(idents1);
86         pdpHeartbeatListener.onTopicEvent(INFRA, TOPIC, status1);
87         verifyPdpGroup(DEFAULT_GROUP, 1);
88
89         // Testing pdp heartbeat success case
90         final PdpStatus status2 = new PdpStatus();
91         status2.setName(PDP_NAME);
92         status2.setState(PdpState.ACTIVE);
93         status2.setPdpGroup(DEFAULT_GROUP);
94         status2.setPdpType(APEX_TYPE);
95         status2.setHealthy(PdpHealthStatus.HEALTHY);
96         status2.setPdpSubgroup(APEX_TYPE);
97         final List<ToscaConceptIdentifier> idents2 =
98                 Arrays.asList(new ToscaConceptIdentifier(POLICY_NAME, POLICY_VERSION));
99         status2.setPolicies(idents2);
100         pdpHeartbeatListener.onTopicEvent(INFRA, TOPIC, status2);
101         verifyPdpGroup(DEFAULT_GROUP, 1);
102
103         // Testing pdp heartbeat failure case with pdp missing
104         final PdpStatus status3 = new PdpStatus();
105         status3.setName("pdp_2");
106         status3.setState(PdpState.ACTIVE);
107         status3.setPdpGroup(DEFAULT_GROUP);
108         status3.setPdpType(APEX_TYPE);
109         status3.setHealthy(PdpHealthStatus.HEALTHY);
110         status3.setPdpSubgroup(APEX_TYPE);
111         final List<ToscaConceptIdentifier> idents3 =
112                 Arrays.asList(new ToscaConceptIdentifier(POLICY_NAME, POLICY_VERSION));
113         status3.setPolicies(idents3);
114         pdpHeartbeatListener.onTopicEvent(INFRA, TOPIC, status3);
115         verifyPdpGroup(DEFAULT_GROUP, 2);
116
117         // Testing pdp registration failure case
118         final PdpStatus status4 = new PdpStatus();
119         status4.setName("pdp_3");
120         status4.setState(PdpState.ACTIVE);
121         status4.setPdpGroup("wrongGroup");
122         status4.setPdpType(APEX_TYPE);
123         status4.setHealthy(PdpHealthStatus.HEALTHY);
124         final List<ToscaConceptIdentifier> idents4 =
125                 Arrays.asList(new ToscaConceptIdentifier(POLICY_NAME, POLICY_VERSION));
126         status4.setPolicies(idents4);
127         pdpHeartbeatListener.onTopicEvent(INFRA, TOPIC, status4);
128         verifyPdpGroup(DEFAULT_GROUP, 2);
129
130         // Testing pdp heartbeat failure case with pdp state mismatch
131         final PdpStatus status5 = new PdpStatus();
132         status5.setName(PDP_NAME);
133         status5.setState(PdpState.PASSIVE);
134         status5.setPdpGroup(DEFAULT_GROUP);
135         status5.setPdpType(APEX_TYPE);
136         status5.setHealthy(PdpHealthStatus.HEALTHY);
137         status5.setPdpSubgroup(APEX_TYPE);
138         final List<ToscaConceptIdentifier> idents5 =
139                 Arrays.asList(new ToscaConceptIdentifier(POLICY_NAME, POLICY_VERSION));
140         status5.setPolicies(idents5);
141         pdpHeartbeatListener.onTopicEvent(INFRA, TOPIC, status5);
142         verifyPdpGroup(DEFAULT_GROUP, 2);
143
144         // Testing pdp heartbeat failure case with pdp policies mismatch
145         final PdpStatus status6 = new PdpStatus();
146         status6.setName(PDP_NAME);
147         status6.setState(PdpState.ACTIVE);
148         status6.setPdpGroup(DEFAULT_GROUP);
149         status6.setPdpType(APEX_TYPE);
150         status6.setHealthy(PdpHealthStatus.HEALTHY);
151         status6.setPdpSubgroup(APEX_TYPE);
152         final List<ToscaConceptIdentifier> idents6 =
153                 Arrays.asList(new ToscaConceptIdentifier(POLICY_NAME, POLICY_VERSION),
154                         new ToscaConceptIdentifier("onap.restart.tca", POLICY_VERSION));
155         status6.setPolicies(idents6);
156         pdpHeartbeatListener.onTopicEvent(INFRA, TOPIC, status6);
157         verifyPdpGroup(DEFAULT_GROUP, 2);
158
159         // Testing pdp heartbeat failure case with pdp no policies
160         final PdpStatus status7 = new PdpStatus();
161         status7.setName(PDP_NAME);
162         status7.setState(PdpState.ACTIVE);
163         status7.setPdpGroup(DEFAULT_GROUP);
164         status7.setPdpType(APEX_TYPE);
165         status7.setHealthy(PdpHealthStatus.HEALTHY);
166         status7.setPdpSubgroup(APEX_TYPE);
167         pdpHeartbeatListener.onTopicEvent(INFRA, TOPIC, status7);
168         verifyPdpGroup(DEFAULT_GROUP, 2);
169
170         // Testing old message for pdp_1 - should have no effect
171         final PdpStatus status7b = new PdpStatus();
172         status7b.setTimestampMs(System.currentTimeMillis() - PdpParameters.DEFAULT_MAX_AGE_MS - 1);
173         status7b.setName(PDP_NAME);
174         status7b.setState(PdpState.TERMINATED);
175         status7b.setPdpGroup(DEFAULT_GROUP);
176         status7b.setPdpType(APEX_TYPE);
177         status7b.setPdpSubgroup(APEX_TYPE);
178         status7b.setHealthy(PdpHealthStatus.HEALTHY);
179         final List<ToscaConceptIdentifier> idents7b =
180                 Arrays.asList(new ToscaConceptIdentifier(POLICY_NAME, POLICY_VERSION));
181         status7b.setPolicies(idents7b);
182         pdpHeartbeatListener.onTopicEvent(INFRA, TOPIC, status7b);
183         verifyPdpGroup(DEFAULT_GROUP, 2);
184
185         // Testing pdp termination case for pdp_1
186         final PdpStatus status8 = new PdpStatus();
187         status8.setName(PDP_NAME);
188         status8.setState(PdpState.TERMINATED);
189         status8.setPdpGroup(DEFAULT_GROUP);
190         status8.setPdpType(APEX_TYPE);
191         status8.setPdpSubgroup(APEX_TYPE);
192         status8.setHealthy(PdpHealthStatus.HEALTHY);
193         final List<ToscaConceptIdentifier> idents8 =
194                 Arrays.asList(new ToscaConceptIdentifier(POLICY_NAME, POLICY_VERSION));
195         status8.setPolicies(idents8);
196         pdpHeartbeatListener.onTopicEvent(INFRA, TOPIC, status8);
197         verifyPdpGroup(DEFAULT_GROUP, 1);
198
199         // Testing pdp termination case for pdp_2
200         final PdpStatus status9 = new PdpStatus();
201         status9.setName("pdp_2");
202         status9.setState(PdpState.TERMINATED);
203         status9.setPdpGroup(DEFAULT_GROUP);
204         status9.setPdpType(APEX_TYPE);
205         status9.setPdpSubgroup(APEX_TYPE);
206         status9.setHealthy(PdpHealthStatus.HEALTHY);
207         final List<ToscaConceptIdentifier> idents9 =
208                 Arrays.asList(new ToscaConceptIdentifier(POLICY_NAME, POLICY_VERSION));
209         status9.setPolicies(idents9);
210         pdpHeartbeatListener.onTopicEvent(INFRA, TOPIC, status9);
211         verifyPdpGroup(DEFAULT_GROUP, 0);
212
213         // Test policy lists updated in createUpdate
214         ToscaPolicy polA = new ToscaPolicy();
215         polA.setName("pol-a-1.1.1");
216         polA.setVersion("1.1.1");
217         ToscaPolicy polB = new ToscaPolicy();
218         polB.setName("pol-b-1.1.1");
219         polB.setVersion("1.1.1");
220         List<ToscaPolicy> policies = new ArrayList<>();
221         policies.add(polA);
222         policies.add(polB);
223         final CommonTestData testData = new CommonTestData();
224         PdpParameters params = testData.getPapParameterGroup(1).getPdpParameters();
225         List<ToscaConceptIdentifier> polsUndep = policies.stream().map(ToscaPolicy::getIdentifier)
226                 .collect(Collectors.toList());
227         PdpStatusMessageHandler handler = new PdpStatusMessageHandler(params);
228         PdpUpdate update10 = handler.createPdpUpdateMessage(
229                 status3.getPdpGroup(), new PdpSubGroup(), "pdp_2",
230                 null, policies, policies, polsUndep);
231         assertSame(update10.getPolicies(), policies);
232         assertSame(update10.getPoliciesToBeDeployed(), policies);
233         assertSame(update10.getPoliciesToBeUndeployed(), polsUndep);
234         assertThat(update10.getPoliciesToBeDeployed()).isInstanceOf(List.class);
235     }
236
237     @Test
238     public void testPdpStatistics() throws CoderException, PfModelException, ParseException {
239         addGroups("PdpGroups.json");
240         pdpHeartbeatListener = new PdpHeartbeatListener(new PdpParameters());
241         timeStamp = Instant.parse("2021-02-12T17:48:01.029211400Z");
242
243         // init default pdp group
244         final PdpStatus status1 = new PdpStatus();
245         status1.setName(PDP_NAME);
246         status1.setState(PdpState.ACTIVE);
247         status1.setPdpGroup(DEFAULT_GROUP);
248         status1.setPdpType(APEX_TYPE);
249         status1.setHealthy(PdpHealthStatus.HEALTHY);
250         final List<ToscaConceptIdentifier> idents1 =
251                 Arrays.asList(new ToscaConceptIdentifier(POLICY_NAME, POLICY_VERSION));
252         status1.setPolicies(idents1);
253         pdpHeartbeatListener.onTopicEvent(INFRA, TOPIC, status1);
254         verifyPdpGroup(DEFAULT_GROUP, 1);
255
256         // init pdp instance
257         final PdpStatus status2 = new PdpStatus();
258         status2.setName(PDP_NAME);
259         status2.setState(PdpState.ACTIVE);
260         status2.setPdpGroup(DEFAULT_GROUP);
261         status2.setPdpType(APEX_TYPE);
262         status2.setHealthy(PdpHealthStatus.HEALTHY);
263         status2.setPdpSubgroup(APEX_TYPE);
264         final List<ToscaConceptIdentifier> idents2 =
265                 Arrays.asList(new ToscaConceptIdentifier(POLICY_NAME, POLICY_VERSION));
266         status2.setPolicies(idents2);
267         pdpHeartbeatListener.onTopicEvent(INFRA, TOPIC, status2);
268
269         // Testing passing pdp statistics success case
270         final PdpStatus status3 = new PdpStatus();
271         status3.setName(PDP_NAME);
272         status3.setState(PdpState.ACTIVE);
273         status3.setPdpGroup(DEFAULT_GROUP);
274         status3.setPdpType(APEX_TYPE);
275         status3.setHealthy(PdpHealthStatus.HEALTHY);
276         status3.setPdpSubgroup(APEX_TYPE);
277         final List<ToscaConceptIdentifier> idents3 =
278                 Arrays.asList(new ToscaConceptIdentifier(POLICY_NAME, POLICY_VERSION));
279         status3.setPolicies(idents3);
280
281         PdpStatistics pdpStatistics03 = new PdpStatistics();
282         pdpStatistics03.setPdpInstanceId(PDP_NAME);
283         pdpStatistics03.setPdpGroupName(DEFAULT_GROUP);
284         pdpStatistics03.setPdpSubGroupName(APEX_TYPE);
285         pdpStatistics03.setTimeStamp(timeStamp);
286         status3.setStatistics(pdpStatistics03);
287         pdpHeartbeatListener.onTopicEvent(INFRA, TOPIC, status3);
288         verifyPdpStatistics(PDP_NAME, DEFAULT_GROUP, null, 1);
289
290         // Testing pdp statistics failure having the pdpStatistics null in the heartbeat for already registered pdp
291         final PdpStatus status4 = new PdpStatus();
292         status4.setName(PDP_NAME);
293         status4.setState(PdpState.ACTIVE);
294         status4.setPdpGroup(DEFAULT_GROUP);
295         status4.setPdpType(APEX_TYPE);
296         status4.setHealthy(PdpHealthStatus.HEALTHY);
297         status4.setPdpSubgroup(APEX_TYPE);
298         final List<ToscaConceptIdentifier> idents4 =
299                 Arrays.asList(new ToscaConceptIdentifier(POLICY_NAME, POLICY_VERSION));
300         status4.setPolicies(idents4);
301         status4.setStatistics(null);
302         pdpHeartbeatListener.onTopicEvent(INFRA, TOPIC, status4);
303         verifyPdpStatistics(PDP_NAME, DEFAULT_GROUP, null, 1);
304
305         // Testing pdp statistics failure passing different pdpGroup, PdpSubGroup & pdpInstanceId
306         final PdpStatus status5 = new PdpStatus();
307         status5.setName(PDP_NAME);
308         status5.setState(PdpState.ACTIVE);
309         status5.setPdpGroup(DEFAULT_GROUP);
310         status5.setPdpType(APEX_TYPE);
311         status5.setHealthy(PdpHealthStatus.HEALTHY);
312         status5.setPdpSubgroup(APEX_TYPE);
313         final List<ToscaConceptIdentifier> idents5 =
314                 Arrays.asList(new ToscaConceptIdentifier(POLICY_NAME, POLICY_VERSION));
315         status5.setPolicies(idents5);
316
317         PdpStatistics pdpStatistics05 = new PdpStatistics();
318         pdpStatistics05.setPdpInstanceId("pdp_2");
319         pdpStatistics05.setPdpGroupName("defaultGroup_1");
320         pdpStatistics05.setPdpSubGroupName("apex_1");
321         pdpStatistics03.setTimeStamp(timeStamp);
322         status5.setStatistics(pdpStatistics05);
323
324         pdpHeartbeatListener.onTopicEvent(INFRA, TOPIC, status5);
325         verifyPdpStatistics(null, DEFAULT_GROUP, null, 1);
326
327         // Test pdp statistics failure passing negative values
328         final PdpStatus status6 = new PdpStatus();
329         status6.setName(PDP_NAME);
330         status6.setState(PdpState.ACTIVE);
331         status6.setPdpGroup(DEFAULT_GROUP);
332         status6.setPdpType(APEX_TYPE);
333         status6.setHealthy(PdpHealthStatus.HEALTHY);
334         status6.setPdpSubgroup(APEX_TYPE);
335         final List<ToscaConceptIdentifier> idents6 =
336                 Arrays.asList(new ToscaConceptIdentifier(POLICY_NAME, POLICY_VERSION));
337         status5.setPolicies(idents6);
338
339         PdpStatistics pdpStatistics06 = new PdpStatistics();
340         pdpStatistics06.setPdpInstanceId(PDP_NAME);
341         pdpStatistics06.setPdpGroupName(DEFAULT_GROUP);
342         pdpStatistics06.setPdpSubGroupName(APEX_TYPE);
343         pdpStatistics03.setTimeStamp(timeStamp);
344
345         pdpStatistics06.setPolicyDeployCount(-1);
346         pdpStatistics06.setPolicyDeployFailCount(-1);
347         status5.setStatistics(pdpStatistics06);
348
349         pdpHeartbeatListener.onTopicEvent(INFRA, TOPIC, status5);
350         verifyPdpStatistics(null, DEFAULT_GROUP, null, 1);
351     }
352
353     private void verifyPdpGroup(final String name, final int count) throws PfModelException {
354         final List<PdpGroup> fetchedGroups = fetchGroups(name);
355         for (final PdpSubGroup subGroup : fetchedGroups.get(0).getPdpSubgroups()) {
356             if (subGroup.getPdpType().equals(APEX_TYPE)) {
357                 assertEquals(count, subGroup.getPdpInstances().size());
358                 assertEquals(count, subGroup.getCurrentInstanceCount());
359                 if (count > 0) {
360                     assertEquals(PdpHealthStatus.HEALTHY, subGroup.getPdpInstances().get(0).getHealthy());
361                 }
362             }
363         }
364     }
365
366     private void verifyPdpStatistics(final String pdpInstanceId, final String pdpGroupName,
367             final String pdpSubGroupName, final int count) throws  PfModelException {
368         final List<PdpStatistics> fetchedPdpStatistics =
369                 fetchPdpStatistics(pdpInstanceId, pdpGroupName, pdpSubGroupName);
370         assertEquals(count, fetchedPdpStatistics.size());
371     }
372 }