2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2019-2022 AT&T Intellectual Property. All rights reserved.
4 * Modifications Copyright (C) 2021, 2024 Nordix Foundation.
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.drools.lifecycle;
24 import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
25 import static org.junit.jupiter.api.Assertions.assertEquals;
26 import static org.junit.jupiter.api.Assertions.assertFalse;
27 import static org.junit.jupiter.api.Assertions.assertNotEquals;
28 import static org.junit.jupiter.api.Assertions.assertNotNull;
29 import static org.junit.jupiter.api.Assertions.assertTrue;
31 import java.io.IOException;
32 import java.nio.charset.StandardCharsets;
33 import java.nio.file.Files;
34 import java.nio.file.Paths;
35 import java.util.ArrayList;
36 import java.util.List;
37 import java.util.Objects;
38 import java.util.concurrent.TimeUnit;
39 import org.junit.jupiter.api.BeforeEach;
40 import org.junit.jupiter.api.Test;
41 import org.onap.policy.common.utils.coder.CoderException;
42 import org.onap.policy.common.utils.coder.StandardCoder;
43 import org.onap.policy.drools.system.PolicyEngineConstants;
44 import org.onap.policy.models.pdp.concepts.PdpStateChange;
45 import org.onap.policy.models.pdp.concepts.PdpStatus;
46 import org.onap.policy.models.pdp.concepts.PdpUpdate;
47 import org.onap.policy.models.pdp.enums.PdpState;
48 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
49 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
52 * Lifecycle State Active Test.
54 class LifecycleStateActiveTest extends LifecycleStateRunningTest {
56 private static final String POLICY_COMPLIANT_VCPE_BAD_INTEGER_JSON =
57 "src/test/resources/tosca-policy-compliant-vcpe-bad-integer.json";
60 * Start tests in the Active state.
63 public void startActive() throws CoderException {
64 fsm = makeFsmWithPseudoTime();
66 fsm.setStatusTimerSeconds(15);
67 assertTrue(fsm.start());
73 private void goActive() throws CoderException {
74 PdpStateChange change = new PdpStateChange();
75 change.setPdpGroup("A");
76 change.setPdpSubgroup("a");
77 change.setState(PdpState.ACTIVE);
78 change.setName(fsm.getPdpName());
81 fsm.source.offer(new StandardCoder().encode(change));
82 controllerSupport.getController().start();
87 assertThatIllegalArgumentException().isThrownBy(() -> new LifecycleStateActive(null));
94 assertFalse(fsm.start());
100 private void assertActive() {
101 assertEquals(PdpState.ACTIVE, fsm.state());
102 assertEquals(LifecycleFsm.DEFAULT_PDP_GROUP, fsm.getGroup());
103 assertEquals("a", fsm.getSubGroup());
104 assertTrue(fsm.isAlive());
105 waitUntil(fsm.getStatusTimerSeconds() + 1, TimeUnit.SECONDS, isStatus(PdpState.ACTIVE));
110 assertTrue(fsm.stop());
111 assertBasicTerminated();
116 private void assertBasicTerminated() {
117 assertEquals(PdpState.TERMINATED, fsm.state());
118 assertFalse(fsm.isAlive());
119 assertFalse(fsm.state.isAlive());
120 waitUntil(1, TimeUnit.SECONDS, isStatus(PdpState.TERMINATED));
124 void testShutdown() {
127 assertBasicTerminated();
129 assertTrue(fsm.statusTask.isCancelled());
130 assertTrue(fsm.statusTask.isDone());
135 waitUntil(fsm.getStatusTimerSeconds() + 1, TimeUnit.SECONDS, isStatus(PdpState.ACTIVE));
136 int preCount = fsm.client.getSink().getRecentEvents().length;
138 assertTrue(fsm.status());
139 assertEquals(preCount + 1, fsm.client.getSink().getRecentEvents().length);
141 fsm.start(controllerSupport.getController());
142 assertTrue(fsm.status());
143 assertEquals(preCount + 2, fsm.client.getSink().getRecentEvents().length);
145 fsm.stop(controllerSupport.getController());
150 void testStateChange() throws CoderException {
153 /* no name and mismatching group info */
154 PdpStateChange change = new PdpStateChange();
155 change.setPdpGroup("B");
156 change.setPdpSubgroup("b");
157 change.setState(PdpState.ACTIVE);
159 fsm.source.offer(new StandardCoder().encode(change));
160 assertEquals(PdpState.ACTIVE, fsm.state());
161 assertEquals(LifecycleFsm.DEFAULT_PDP_GROUP, fsm.getGroup());
162 assertNotEquals("b", fsm.getSubGroup());
164 change.setName(fsm.getPdpName());
165 fsm.source.offer(new StandardCoder().encode(change));
166 assertEquals(PdpState.ACTIVE, fsm.state());
167 assertEquals(LifecycleFsm.DEFAULT_PDP_GROUP, fsm.getGroup());
168 assertEquals("a", fsm.getSubGroup());
170 change.setState(PdpState.SAFE);
171 fsm.source.offer(new StandardCoder().encode(change));
172 assertEquals(PdpState.ACTIVE, fsm.state());
174 change.setState(PdpState.TERMINATED);
175 fsm.source.offer(new StandardCoder().encode(change));
176 assertEquals(PdpState.ACTIVE, fsm.state());
178 change.setState(PdpState.PASSIVE);
179 fsm.source.offer(new StandardCoder().encode(change));
180 assertEquals(PdpState.PASSIVE, fsm.state());
181 waitUntil(fsm.getStatusTimerSeconds() + 1, TimeUnit.SECONDS, isStatus(PdpState.PASSIVE));
187 void testUpdate() throws IOException, CoderException {
189 // TODO: extract repeated similar assertion blocks into their own helper methods
191 PdpUpdate update = new PdpUpdate();
192 update.setName(PolicyEngineConstants.getManager().getPdpName());
193 update.setPdpGroup("W");
194 update.setPdpSubgroup("w");
196 fsm.start(controllerSupport.getController());
197 assertTrue(fsm.update(update));
199 assertEquals(PdpState.ACTIVE, fsm.state());
200 assertEquals(LifecycleFsm.DEFAULT_PDP_GROUP, fsm.getGroup());
201 assertEquals("w", fsm.getSubGroup());
203 ToscaPolicy toscaPolicyRestartV1 =
204 getExamplesPolicy("policies/vCPE.policy.operational.input.tosca.json", "operational.restart");
205 toscaPolicyRestartV1.getProperties().put("controllerName", "lifecycle");
206 update.setPoliciesToBeDeployed(List.of(toscaPolicyRestartV1));
208 int qlength = fsm.client.getSink().getRecentEvents().length;
210 // update with an operational.restart policy
212 assertTrue(fsm.update(update));
213 assertEquals(qlength + 1, fsm.client.getSink().getRecentEvents().length);
214 assertEquals(3, fsm.policyTypesMap.size());
215 assertNotNull(fsm.getPolicyTypesMap().get(
216 new ToscaConceptIdentifier("onap.policies.native.drools.Controller", "1.0.0")));
217 assertNotNull(fsm.getPolicyTypesMap().get(
218 new ToscaConceptIdentifier("onap.policies.native.drools.Artifact", "1.0.0")));
219 assertNotNull(fsm.getPolicyTypesMap().get(
220 new ToscaConceptIdentifier("onap.policies.controlloop.operational.common.Drools",
222 PdpStatus cachedStatus = new StandardCoder()
223 .decode(fsm.client.getSink().getRecentEvents()[qlength], PdpStatus.class);
224 assertEquals("foo", cachedStatus.getPdpType());
225 assertEquals(new ArrayList<>(fsm.policiesMap.keySet()), cachedStatus.getPolicies());
227 List<ToscaPolicy> factPolicies = controllerSupport.getFacts(ToscaPolicy.class);
228 assertEquals(1, factPolicies.size());
229 assertEquals(toscaPolicyRestartV1, factPolicies.get(0));
230 assertEquals(1, fsm.policiesMap.size());
232 // dup update with the same operational.restart policy - nothing changes
234 assertTrue(fsm.update(update));
235 assertEquals(qlength + 2, fsm.client.getSink().getRecentEvents().length);
236 assertEquals(3, fsm.policyTypesMap.size());
237 cachedStatus = new StandardCoder()
238 .decode(fsm.client.getSink().getRecentEvents()[qlength + 1], PdpStatus.class);
239 assertEquals(new ArrayList<>(fsm.policiesMap.keySet()), cachedStatus.getPolicies());
241 factPolicies = controllerSupport.getFacts(ToscaPolicy.class);
242 assertEquals(1, factPolicies.size());
243 assertEquals(toscaPolicyRestartV1, factPolicies.get(0));
244 assertEquals(1, fsm.policiesMap.size());
246 // undeploy operational.restart policy
248 update.setPoliciesToBeDeployed(List.of());
249 update.setPoliciesToBeUndeployed(List.of(toscaPolicyRestartV1.getIdentifier()));
250 assertTrue(fsm.update(update));
251 assertEquals(qlength + 3, fsm.client.getSink().getRecentEvents().length);
252 assertEquals(3, fsm.policyTypesMap.size());
253 cachedStatus = new StandardCoder()
254 .decode(fsm.client.getSink().getRecentEvents()[qlength + 2], PdpStatus.class);
255 assertEquals(new ArrayList<>(fsm.policiesMap.keySet()), cachedStatus.getPolicies());
257 factPolicies = controllerSupport.getFacts(ToscaPolicy.class);
258 assertEquals(0, factPolicies.size());
259 assertEquals(0, fsm.policiesMap.size());
261 // redeploy operational.restart policy
263 update.setPoliciesToBeUndeployed(List.of());
264 update.setPoliciesToBeDeployed(List.of(toscaPolicyRestartV1));
265 assertTrue(fsm.update(update));
266 assertEquals(qlength + 4, fsm.client.getSink().getRecentEvents().length);
267 assertEquals(3, fsm.policyTypesMap.size());
268 cachedStatus = new StandardCoder()
269 .decode(fsm.client.getSink().getRecentEvents()[qlength + 3], PdpStatus.class);
270 assertEquals(new ArrayList<>(fsm.policiesMap.keySet()), cachedStatus.getPolicies());
272 factPolicies = controllerSupport.getFacts(ToscaPolicy.class);
273 assertEquals(1, factPolicies.size());
274 assertEquals(toscaPolicyRestartV1, factPolicies.get(0));
275 assertEquals(1, fsm.policiesMap.size());
277 // deploy a new version of the operational.restart policy
279 ToscaPolicy toscaPolicyRestartV2 =
280 getExamplesPolicy("policies/vCPE.policy.operational.input.tosca.json", "operational.restart");
281 toscaPolicyRestartV2.setVersion("2.0.0");
282 toscaPolicyRestartV2.getProperties().put("controllerName", "lifecycle");
283 update.setPoliciesToBeUndeployed(List.of(toscaPolicyRestartV1.getIdentifier()));
284 update.setPoliciesToBeDeployed(List.of(toscaPolicyRestartV2));
285 assertTrue(fsm.update(update));
286 assertEquals(qlength + 5, fsm.client.getSink().getRecentEvents().length);
287 assertEquals(3, fsm.policyTypesMap.size());
288 cachedStatus = new StandardCoder()
289 .decode(fsm.client.getSink().getRecentEvents()[qlength + 4], PdpStatus.class);
290 assertEquals(new ArrayList<>(fsm.policiesMap.keySet()), cachedStatus.getPolicies());
292 factPolicies = controllerSupport.getFacts(ToscaPolicy.class);
293 assertEquals(1, factPolicies.size());
294 assertNotEquals(toscaPolicyRestartV1, factPolicies.get(0));
295 assertEquals(toscaPolicyRestartV2, factPolicies.get(0));
296 assertEquals(1, fsm.policiesMap.size());
298 // deploy another policy : firewall
300 ToscaPolicy toscaPolicyFirewall =
301 getExamplesPolicy("policies/vFirewall.policy.operational.input.tosca.json", "operational.modifyconfig");
302 toscaPolicyFirewall.getProperties().put("controllerName", "lifecycle");
303 update.setPoliciesToBeUndeployed(List.of());
304 update.setPoliciesToBeDeployed(List.of(toscaPolicyRestartV2, toscaPolicyFirewall));
305 assertTrue(fsm.update(update));
306 assertEquals(qlength + 6, fsm.client.getSink().getRecentEvents().length);
307 assertEquals(3, fsm.policyTypesMap.size());
308 cachedStatus = new StandardCoder()
309 .decode(fsm.client.getSink().getRecentEvents()[qlength + 5], PdpStatus.class);
310 assertEquals(new ArrayList<>(fsm.policiesMap.keySet()), cachedStatus.getPolicies());
312 factPolicies = controllerSupport.getFacts(ToscaPolicy.class);
313 assertEquals(2, factPolicies.size());
314 assertTrue(factPolicies.stream().noneMatch((ff) -> Objects.equals(toscaPolicyRestartV1, ff)));
315 assertTrue(factPolicies.stream().anyMatch((ff) -> Objects.equals(toscaPolicyRestartV2, ff)));
316 assertTrue(factPolicies.stream().anyMatch((ff) -> Objects.equals(toscaPolicyFirewall, ff)));
317 assertEquals(2, fsm.policiesMap.size());
319 long originalInterval = fsm.getStatusTimerSeconds();
320 long interval = 10 * originalInterval;
321 update.setPdpHeartbeatIntervalMs(interval * 1000L);
323 update.setPoliciesToBeUndeployed(List.of());
324 update.setPoliciesToBeDeployed(List.of());
325 assertTrue(fsm.update(update));
327 assertEquals(PdpState.ACTIVE, fsm.state());
328 assertEquals(interval, fsm.getStatusTimerSeconds());
330 // bad policy deployment
332 String badIntegerPolicy =
333 Files.readString(Paths.get(POLICY_COMPLIANT_VCPE_BAD_INTEGER_JSON), StandardCharsets.UTF_8);
334 ToscaPolicy toscaPolicyRestartBad = new StandardCoder().decode(badIntegerPolicy, ToscaPolicy.class);
335 update.setPoliciesToBeUndeployed(List.of(toscaPolicyRestartV2.getIdentifier(),
336 toscaPolicyFirewall.getIdentifier()));
337 update.setPoliciesToBeDeployed(List.of(toscaPolicyRestartBad));
338 assertFalse(fsm.update(update));
340 assertTrue(controllerSupport.getController().getDrools().delete(ToscaPolicy.class));