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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * SPDX-License-Identifier: Apache-2.0
19 * ============LICENSE_END=========================================================
22 package org.onap.policy.pap.main.comm;
24 import static org.assertj.core.api.Assertions.assertThat;
25 import static org.junit.Assert.assertEquals;
26 import static org.junit.Assert.assertSame;
28 import java.text.ParseException;
29 import java.time.Instant;
30 import java.util.ArrayList;
31 import java.util.Arrays;
32 import java.util.List;
33 import java.util.stream.Collectors;
34 import org.junit.Test;
35 import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure;
36 import org.onap.policy.common.utils.coder.CoderException;
37 import org.onap.policy.models.base.PfModelException;
38 import org.onap.policy.models.pdp.concepts.PdpGroup;
39 import org.onap.policy.models.pdp.concepts.PdpStatistics;
40 import org.onap.policy.models.pdp.concepts.PdpStatus;
41 import org.onap.policy.models.pdp.concepts.PdpSubGroup;
42 import org.onap.policy.models.pdp.concepts.PdpUpdate;
43 import org.onap.policy.models.pdp.enums.PdpHealthStatus;
44 import org.onap.policy.models.pdp.enums.PdpState;
45 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
46 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
47 import org.onap.policy.pap.main.parameters.CommonTestData;
48 import org.onap.policy.pap.main.parameters.PdpParameters;
49 import org.onap.policy.pap.main.rest.e2e.End2EndBase;
52 * Class to perform unit test of {@link PdpHeartbeatListener}.
54 * @author Ram Krishna Verma (ram.krishna.verma@est.tech)
56 public class PdpHeartbeatListenerTest extends End2EndBase {
58 private static final String POLICY_VERSION = "1.0.0";
59 private static final String POLICY_NAME = "onap.policies.controlloop.operational.common.apex.SampleDomain";
60 private static final String APEX_TYPE = "apex";
61 private static final String DEFAULT_GROUP = "defaultGroup";
62 private static final String PDP_NAME = "pdp_1";
63 private static final CommInfrastructure INFRA = CommInfrastructure.NOOP;
64 private static final String TOPIC = "my-topic";
66 private Instant timeStamp;
67 private PdpHeartbeatListener pdpHeartbeatListener;
70 public void testPdpHeartbeatListener() throws CoderException, PfModelException {
71 addGroups("PdpGroups.json");
72 pdpHeartbeatListener = new PdpHeartbeatListener(new PdpParameters());
74 // Testing pdp registration success case
75 final PdpStatus status1 = new PdpStatus();
76 status1.setName(PDP_NAME);
77 status1.setState(PdpState.ACTIVE);
78 status1.setPdpGroup(DEFAULT_GROUP);
79 status1.setPdpType(APEX_TYPE);
80 status1.setHealthy(PdpHealthStatus.HEALTHY);
81 final List<ToscaConceptIdentifier> idents1 =
82 Arrays.asList(new ToscaConceptIdentifier(POLICY_NAME, POLICY_VERSION));
83 status1.setPolicies(idents1);
84 pdpHeartbeatListener.onTopicEvent(INFRA, TOPIC, status1);
85 verifyPdpGroup(DEFAULT_GROUP, 1);
87 // Testing pdp heartbeat success case
88 final PdpStatus status2 = new PdpStatus();
89 status2.setName(PDP_NAME);
90 status2.setState(PdpState.ACTIVE);
91 status2.setPdpGroup(DEFAULT_GROUP);
92 status2.setPdpType(APEX_TYPE);
93 status2.setHealthy(PdpHealthStatus.HEALTHY);
94 status2.setPdpSubgroup(APEX_TYPE);
95 final List<ToscaConceptIdentifier> idents2 =
96 Arrays.asList(new ToscaConceptIdentifier(POLICY_NAME, POLICY_VERSION));
97 status2.setPolicies(idents2);
98 pdpHeartbeatListener.onTopicEvent(INFRA, TOPIC, status2);
99 verifyPdpGroup(DEFAULT_GROUP, 1);
101 // Testing pdp heartbeat failure case with pdp missing
102 final PdpStatus status3 = new PdpStatus();
103 status3.setName("pdp_2");
104 status3.setState(PdpState.ACTIVE);
105 status3.setPdpGroup(DEFAULT_GROUP);
106 status3.setPdpType(APEX_TYPE);
107 status3.setHealthy(PdpHealthStatus.HEALTHY);
108 status3.setPdpSubgroup(APEX_TYPE);
109 final List<ToscaConceptIdentifier> idents3 =
110 Arrays.asList(new ToscaConceptIdentifier(POLICY_NAME, POLICY_VERSION));
111 status3.setPolicies(idents3);
112 pdpHeartbeatListener.onTopicEvent(INFRA, TOPIC, status3);
113 verifyPdpGroup(DEFAULT_GROUP, 2);
115 // Testing pdp registration failure case
116 final PdpStatus status4 = new PdpStatus();
117 status4.setName("pdp_3");
118 status4.setState(PdpState.ACTIVE);
119 status4.setPdpGroup("wrongGroup");
120 status4.setPdpType(APEX_TYPE);
121 status4.setHealthy(PdpHealthStatus.HEALTHY);
122 final List<ToscaConceptIdentifier> idents4 =
123 Arrays.asList(new ToscaConceptIdentifier(POLICY_NAME, POLICY_VERSION));
124 status4.setPolicies(idents4);
125 pdpHeartbeatListener.onTopicEvent(INFRA, TOPIC, status4);
126 verifyPdpGroup(DEFAULT_GROUP, 2);
128 // Testing pdp heartbeat failure case with pdp state mismatch
129 final PdpStatus status5 = new PdpStatus();
130 status5.setName(PDP_NAME);
131 status5.setState(PdpState.PASSIVE);
132 status5.setPdpGroup(DEFAULT_GROUP);
133 status5.setPdpType(APEX_TYPE);
134 status5.setHealthy(PdpHealthStatus.HEALTHY);
135 status5.setPdpSubgroup(APEX_TYPE);
136 final List<ToscaConceptIdentifier> idents5 =
137 Arrays.asList(new ToscaConceptIdentifier(POLICY_NAME, POLICY_VERSION));
138 status5.setPolicies(idents5);
139 pdpHeartbeatListener.onTopicEvent(INFRA, TOPIC, status5);
140 verifyPdpGroup(DEFAULT_GROUP, 2);
142 // Testing pdp heartbeat failure case with pdp policies mismatch
143 final PdpStatus status6 = new PdpStatus();
144 status6.setName(PDP_NAME);
145 status6.setState(PdpState.ACTIVE);
146 status6.setPdpGroup(DEFAULT_GROUP);
147 status6.setPdpType(APEX_TYPE);
148 status6.setHealthy(PdpHealthStatus.HEALTHY);
149 status6.setPdpSubgroup(APEX_TYPE);
150 final List<ToscaConceptIdentifier> idents6 =
151 Arrays.asList(new ToscaConceptIdentifier(POLICY_NAME, POLICY_VERSION),
152 new ToscaConceptIdentifier("onap.restart.tca", POLICY_VERSION));
153 status6.setPolicies(idents6);
154 pdpHeartbeatListener.onTopicEvent(INFRA, TOPIC, status6);
155 verifyPdpGroup(DEFAULT_GROUP, 2);
157 // Testing pdp heartbeat failure case with pdp no policies
158 final PdpStatus status7 = new PdpStatus();
159 status7.setName(PDP_NAME);
160 status7.setState(PdpState.ACTIVE);
161 status7.setPdpGroup(DEFAULT_GROUP);
162 status7.setPdpType(APEX_TYPE);
163 status7.setHealthy(PdpHealthStatus.HEALTHY);
164 status7.setPdpSubgroup(APEX_TYPE);
165 pdpHeartbeatListener.onTopicEvent(INFRA, TOPIC, status7);
166 verifyPdpGroup(DEFAULT_GROUP, 2);
168 // Testing old message for pdp_1 - should have no effect
169 final PdpStatus status7b = new PdpStatus();
170 status7b.setTimestampMs(System.currentTimeMillis() - PdpParameters.DEFAULT_MAX_AGE_MS - 1);
171 status7b.setName(PDP_NAME);
172 status7b.setState(PdpState.TERMINATED);
173 status7b.setPdpGroup(DEFAULT_GROUP);
174 status7b.setPdpType(APEX_TYPE);
175 status7b.setPdpSubgroup(APEX_TYPE);
176 status7b.setHealthy(PdpHealthStatus.HEALTHY);
177 final List<ToscaConceptIdentifier> idents7b =
178 Arrays.asList(new ToscaConceptIdentifier(POLICY_NAME, POLICY_VERSION));
179 status7b.setPolicies(idents7b);
180 pdpHeartbeatListener.onTopicEvent(INFRA, TOPIC, status7b);
181 verifyPdpGroup(DEFAULT_GROUP, 2);
183 // Testing pdp termination case for pdp_1
184 final PdpStatus status8 = new PdpStatus();
185 status8.setName(PDP_NAME);
186 status8.setState(PdpState.TERMINATED);
187 status8.setPdpGroup(DEFAULT_GROUP);
188 status8.setPdpType(APEX_TYPE);
189 status8.setPdpSubgroup(APEX_TYPE);
190 status8.setHealthy(PdpHealthStatus.HEALTHY);
191 final List<ToscaConceptIdentifier> idents8 =
192 Arrays.asList(new ToscaConceptIdentifier(POLICY_NAME, POLICY_VERSION));
193 status8.setPolicies(idents8);
194 pdpHeartbeatListener.onTopicEvent(INFRA, TOPIC, status8);
195 verifyPdpGroup(DEFAULT_GROUP, 1);
197 // Testing pdp termination case for pdp_2
198 final PdpStatus status9 = new PdpStatus();
199 status9.setName("pdp_2");
200 status9.setState(PdpState.TERMINATED);
201 status9.setPdpGroup(DEFAULT_GROUP);
202 status9.setPdpType(APEX_TYPE);
203 status9.setPdpSubgroup(APEX_TYPE);
204 status9.setHealthy(PdpHealthStatus.HEALTHY);
205 final List<ToscaConceptIdentifier> idents9 =
206 Arrays.asList(new ToscaConceptIdentifier(POLICY_NAME, POLICY_VERSION));
207 status9.setPolicies(idents9);
208 pdpHeartbeatListener.onTopicEvent(INFRA, TOPIC, status9);
209 verifyPdpGroup(DEFAULT_GROUP, 0);
211 // Test policy lists updated in createUpdate
212 ToscaPolicy polA = new ToscaPolicy();
213 polA.setName("pol-a-1.1.1");
214 polA.setVersion("1.1.1");
215 ToscaPolicy polB = new ToscaPolicy();
216 polB.setName("pol-b-1.1.1");
217 polB.setVersion("1.1.1");
218 List<ToscaPolicy> policies = new ArrayList<>();
221 final CommonTestData testData = new CommonTestData();
222 PdpParameters params = testData.getPapParameterGroup(1).getPdpParameters();
223 List<ToscaConceptIdentifier> polsUndep = policies.stream().map(ToscaPolicy::getIdentifier)
224 .collect(Collectors.toList());
225 PdpStatusMessageHandler handler = new PdpStatusMessageHandler(params);
226 PdpUpdate update10 = handler.createPdpUpdateMessage(
227 status3.getPdpGroup(), new PdpSubGroup(), "pdp_2",
228 null, policies, policies, polsUndep);
229 assertSame(update10.getPolicies(), policies);
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());
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);
351 private void verifyPdpGroup(final String name, final int count) throws PfModelException {
352 final List<PdpGroup> fetchedGroups = fetchGroups(name);
353 for (final PdpSubGroup subGroup : fetchedGroups.get(0).getPdpSubgroups()) {
354 if (subGroup.getPdpType().equals(APEX_TYPE)) {
355 assertEquals(count, subGroup.getPdpInstances().size());
356 assertEquals(count, subGroup.getCurrentInstanceCount());
358 assertEquals(PdpHealthStatus.HEALTHY, subGroup.getPdpInstances().get(0).getHealthy());
364 private void verifyPdpStatistics(final String pdpInstanceId, final String pdpGroupName,
365 final String pdpSubGroupName, final int count) throws PfModelException {
366 final List<PdpStatistics> fetchedPdpStatistics =
367 fetchPdpStatistics(pdpInstanceId, pdpGroupName, pdpSubGroupName);
368 assertEquals(count, fetchedPdpStatistics.size());