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