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