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.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;
54 * Class to perform unit test of {@link PdpHeartbeatListener}.
56 * @author Ram Krishna Verma (ram.krishna.verma@est.tech)
58 public class PdpHeartbeatListenerTest extends End2EndBase {
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";
68 private Instant timeStamp;
69 private PdpHeartbeatListener pdpHeartbeatListener;
72 public void testPdpHeartbeatListener() throws CoderException, PfModelException {
73 addGroups("PdpGroups.json");
74 pdpHeartbeatListener = new PdpHeartbeatListener(new PdpParameters());
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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<>();
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);
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");
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);
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);
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);
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);
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);
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);
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);
324 pdpHeartbeatListener.onTopicEvent(INFRA, TOPIC, status5);
325 verifyPdpStatistics(null, DEFAULT_GROUP, null, 1);
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);
339 PdpStatistics pdpStatistics06 = new PdpStatistics();
340 pdpStatistics06.setPdpInstanceId(PDP_NAME);
341 pdpStatistics06.setPdpGroupName(DEFAULT_GROUP);
342 pdpStatistics06.setPdpSubGroupName(APEX_TYPE);
343 pdpStatistics03.setTimeStamp(timeStamp);
345 pdpStatistics06.setPolicyDeployCount(-1);
346 pdpStatistics06.setPolicyDeployFailCount(-1);
347 status5.setStatistics(pdpStatistics06);
349 pdpHeartbeatListener.onTopicEvent(INFRA, TOPIC, status5);
350 verifyPdpStatistics(null, DEFAULT_GROUP, null, 1);
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());
360 assertEquals(PdpHealthStatus.HEALTHY, subGroup.getPdpInstances().get(0).getHealthy());
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());