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
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;
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;
53 * Class to perform unit test of {@link PdpHeartbeatListener}.
55 * @author Ram Krishna Verma (ram.krishna.verma@est.tech)
57 public class PdpHeartbeatListenerTest extends End2EndBase {
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";
67 private Instant timeStamp;
68 private PdpHeartbeatListener pdpHeartbeatListener;
71 public void testPdpHeartbeatListener() throws CoderException, PfModelException {
72 addGroups("PdpGroups.json");
73 pdpHeartbeatListener = new PdpHeartbeatListener(new PdpParameters(), true);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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<>();
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);
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");
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);
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);
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);
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);
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);
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);
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);
322 pdpHeartbeatListener.onTopicEvent(INFRA, TOPIC, status5);
323 verifyPdpStatistics(null, DEFAULT_GROUP, null, 1);
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);
337 PdpStatistics pdpStatistics06 = new PdpStatistics();
338 pdpStatistics06.setPdpInstanceId(PDP_NAME);
339 pdpStatistics06.setPdpGroupName(DEFAULT_GROUP);
340 pdpStatistics06.setPdpSubGroupName(APEX_TYPE);
341 pdpStatistics03.setTimeStamp(timeStamp);
343 pdpStatistics06.setPolicyDeployCount(-1);
344 pdpStatistics06.setPolicyDeployFailCount(-1);
345 status5.setStatistics(pdpStatistics06);
347 pdpHeartbeatListener.onTopicEvent(INFRA, TOPIC, status5);
348 verifyPdpStatistics(null, DEFAULT_GROUP, null, 1);
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);
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);
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());
382 assertEquals(PdpHealthStatus.HEALTHY, subGroup.getPdpInstances().get(0).getHealthy());
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());