support pdp-type configuration for PAP status
[policy/drools-pdp.git] / feature-lifecycle / src / test / java / org / onap / policy / drools / lifecycle / LifecycleStateActiveTest.java
1 /*
2  * ============LICENSE_START=======================================================
3  * Copyright (C) 2019-2021 AT&T Intellectual Property. All rights reserved.
4  * Modifications Copyright (C) 2021 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
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  *
18  * SPDX-License-Identifier: Apache-2.0
19  * =============LICENSE_END========================================================
20  */
21
22 package org.onap.policy.drools.lifecycle;
23
24 import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
25 import static org.junit.Assert.assertEquals;
26 import static org.junit.Assert.assertFalse;
27 import static org.junit.Assert.assertNotEquals;
28 import static org.junit.Assert.assertNotNull;
29 import static org.junit.Assert.assertTrue;
30
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.Arrays;
37 import java.util.Collections;
38 import java.util.List;
39 import java.util.Objects;
40 import java.util.concurrent.TimeUnit;
41 import org.junit.Before;
42 import org.junit.Test;
43 import org.onap.policy.common.utils.coder.CoderException;
44 import org.onap.policy.common.utils.coder.StandardCoder;
45 import org.onap.policy.common.utils.network.NetworkUtil;
46 import org.onap.policy.models.pdp.concepts.PdpStateChange;
47 import org.onap.policy.models.pdp.concepts.PdpStatus;
48 import org.onap.policy.models.pdp.concepts.PdpUpdate;
49 import org.onap.policy.models.pdp.enums.PdpState;
50 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
51 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
52
53 /**
54  * Lifecycle State Active Test.
55  */
56 public class LifecycleStateActiveTest extends LifecycleStateRunningTest {
57
58     private static final String POLICY_COMPLIANT_VCPE_BAD_INTEGER_JSON =
59             "src/test/resources/tosca-policy-compliant-vcpe-bad-integer.json";
60
61     /**
62      * Start tests in the Active state.
63      */
64     @Before
65     public void startActive() throws CoderException {
66         fsm = makeFsmWithPseudoTime();
67
68         fsm.setStatusTimerSeconds(15);
69         assertTrue(fsm.start());
70
71         goActive();
72         assertActive();
73     }
74
75     private void goActive() throws CoderException {
76         PdpStateChange change = new PdpStateChange();
77         change.setPdpGroup("A");
78         change.setPdpSubgroup("a");
79         change.setState(PdpState.ACTIVE);
80         change.setName(fsm.getName());
81
82         fsm.setSubGroup("a");
83         fsm.source.offer(new StandardCoder().encode(change));
84         controllerSupport.getController().start();
85     }
86
87     @Test
88     public void constructor() {
89         assertThatIllegalArgumentException().isThrownBy(() -> new LifecycleStateActive(null));
90         fsm.shutdown();
91     }
92
93     @Test
94     public void testStart() {
95         assertActive();
96         assertFalse(fsm.start());
97         assertActive();
98
99         fsm.shutdown();
100     }
101
102     private void assertActive() {
103         assertEquals(PdpState.ACTIVE, fsm.state());
104         assertEquals(LifecycleFsm.DEFAULT_PDP_GROUP, fsm.getGroup());
105         assertEquals("a", fsm.getSubGroup());
106         assertTrue(fsm.isAlive());
107         waitUntil(fsm.getStatusTimerSeconds() + 1, TimeUnit.SECONDS, isStatus(PdpState.ACTIVE));
108     }
109
110     @Test
111     public void testStop() {
112         assertTrue(fsm.stop());
113         assertBasicTerminated();
114
115         fsm.shutdown();
116     }
117
118     private void assertBasicTerminated() {
119         assertEquals(PdpState.TERMINATED, fsm.state());
120         assertFalse(fsm.isAlive());
121         assertFalse(fsm.state.isAlive());
122         waitUntil(1, TimeUnit.SECONDS, isStatus(PdpState.TERMINATED));
123     }
124
125     @Test
126     public void testShutdown() {
127         fsm.shutdown();
128
129         assertBasicTerminated();
130
131         assertTrue(fsm.statusTask.isCancelled());
132         assertTrue(fsm.statusTask.isDone());
133     }
134
135     @Test
136     public void testStatus() {
137         waitUntil(fsm.getStatusTimerSeconds() + 1, TimeUnit.SECONDS, isStatus(PdpState.ACTIVE));
138         int preCount = fsm.client.getSink().getRecentEvents().length;
139
140         assertTrue(fsm.status());
141         assertEquals(preCount + 1, fsm.client.getSink().getRecentEvents().length);
142
143         fsm.start(controllerSupport.getController());
144         assertTrue(fsm.status());
145         assertEquals(preCount + 2, fsm.client.getSink().getRecentEvents().length);
146
147         fsm.stop(controllerSupport.getController());
148         fsm.shutdown();
149     }
150
151     @Test
152     public void testStateChange() throws CoderException {
153         assertActive();
154
155         /* no name and mismatching group info */
156         PdpStateChange change = new PdpStateChange();
157         change.setPdpGroup("B");
158         change.setPdpSubgroup("b");
159         change.setState(PdpState.ACTIVE);
160
161         fsm.source.offer(new StandardCoder().encode(change));
162         assertEquals(PdpState.ACTIVE, fsm.state());
163         assertEquals(LifecycleFsm.DEFAULT_PDP_GROUP, fsm.getGroup());
164         assertNotEquals("b", fsm.getSubGroup());
165
166         change.setName(fsm.getName());
167         fsm.source.offer(new StandardCoder().encode(change));
168         assertEquals(PdpState.ACTIVE, fsm.state());
169         assertEquals(LifecycleFsm.DEFAULT_PDP_GROUP, fsm.getGroup());
170         assertEquals("a", fsm.getSubGroup());
171
172         change.setState(PdpState.SAFE);
173         fsm.source.offer(new StandardCoder().encode(change));
174         assertEquals(PdpState.ACTIVE, fsm.state());
175
176         change.setState(PdpState.TERMINATED);
177         fsm.source.offer(new StandardCoder().encode(change));
178         assertEquals(PdpState.ACTIVE, fsm.state());
179
180         change.setState(PdpState.PASSIVE);
181         fsm.source.offer(new StandardCoder().encode(change));
182         assertEquals(PdpState.PASSIVE, fsm.state());
183         waitUntil(fsm.getStatusTimerSeconds() + 1, TimeUnit.SECONDS, isStatus(PdpState.PASSIVE));
184
185         fsm.shutdown();
186     }
187
188     @Test
189     public void testUpdate() throws IOException, CoderException {
190
191         // TODO: extract repeated similar assertion blocks into their own helper methods
192
193         PdpUpdate update = new PdpUpdate();
194         update.setName(NetworkUtil.getHostname());
195         update.setPdpGroup("W");
196         update.setPdpSubgroup("w");
197         update.setPolicies(Collections.emptyList());
198
199         fsm.start(controllerSupport.getController());
200         assertTrue(fsm.update(update));
201
202         assertEquals(PdpState.ACTIVE, fsm.state());
203         assertEquals(LifecycleFsm.DEFAULT_PDP_GROUP, fsm.getGroup());
204         assertEquals("w", fsm.getSubGroup());
205
206         ToscaPolicy toscaPolicyRestartV1 =
207             getExamplesPolicy("policies/vCPE.policy.operational.input.tosca.json", "operational.restart");
208         toscaPolicyRestartV1.getProperties().put("controllerName", "lifecycle");
209         update.setPolicies(Collections.singletonList(toscaPolicyRestartV1));
210
211         int qlength = fsm.client.getSink().getRecentEvents().length;
212
213         // update with an operational.restart policy
214
215         assertTrue(fsm.update(update));
216         assertEquals(qlength + 1, fsm.client.getSink().getRecentEvents().length);
217         assertEquals(3, fsm.policyTypesMap.size());
218         assertNotNull(fsm.getPolicyTypesMap().get(
219                 new ToscaConceptIdentifier("onap.policies.native.drools.Controller", "1.0.0")));
220         assertNotNull(fsm.getPolicyTypesMap().get(
221                 new ToscaConceptIdentifier("onap.policies.native.drools.Artifact", "1.0.0")));
222         assertNotNull(fsm.getPolicyTypesMap().get(
223                 new ToscaConceptIdentifier("onap.policies.controlloop.operational.common.Drools",
224                 "1.0.0")));
225         PdpStatus cachedStatus = new StandardCoder()
226                                     .decode(fsm.client.getSink().getRecentEvents()[qlength], PdpStatus.class);
227         assertEquals("foo", cachedStatus.getPdpType());
228         assertEquals(new ArrayList<>(fsm.policiesMap.keySet()), cachedStatus.getPolicies());
229
230         List<ToscaPolicy> factPolicies = controllerSupport.getFacts(ToscaPolicy.class);
231         assertEquals(1, factPolicies.size());
232         assertEquals(toscaPolicyRestartV1, factPolicies.get(0));
233         assertEquals(1, fsm.policiesMap.size());
234
235         // dup update with the same operational.restart policy - nothing changes
236
237         assertTrue(fsm.update(update));
238         assertEquals(qlength + 2, fsm.client.getSink().getRecentEvents().length);
239         assertEquals(3, fsm.policyTypesMap.size());
240         cachedStatus = new StandardCoder()
241             .decode(fsm.client.getSink().getRecentEvents()[qlength + 1], PdpStatus.class);
242         assertEquals(new ArrayList<>(fsm.policiesMap.keySet()), cachedStatus.getPolicies());
243
244         factPolicies = controllerSupport.getFacts(ToscaPolicy.class);
245         assertEquals(1, factPolicies.size());
246         assertEquals(toscaPolicyRestartV1, factPolicies.get(0));
247         assertEquals(1, fsm.policiesMap.size());
248
249         // undeploy operational.restart policy
250
251         update.setPolicies(Collections.emptyList());
252         assertTrue(fsm.update(update));
253         assertEquals(qlength + 3, fsm.client.getSink().getRecentEvents().length);
254         assertEquals(3, fsm.policyTypesMap.size());
255         cachedStatus = new StandardCoder()
256             .decode(fsm.client.getSink().getRecentEvents()[qlength + 2], PdpStatus.class);
257         assertEquals(new ArrayList<>(fsm.policiesMap.keySet()), cachedStatus.getPolicies());
258
259         factPolicies = controllerSupport.getFacts(ToscaPolicy.class);
260         assertEquals(0, factPolicies.size());
261         assertEquals(0, fsm.policiesMap.size());
262
263         // redeploy operational.restart policy
264
265         update.setPolicies(Collections.singletonList(toscaPolicyRestartV1));
266         assertTrue(fsm.update(update));
267         assertEquals(qlength + 4, fsm.client.getSink().getRecentEvents().length);
268         assertEquals(3, fsm.policyTypesMap.size());
269         cachedStatus = new StandardCoder()
270             .decode(fsm.client.getSink().getRecentEvents()[qlength + 3], PdpStatus.class);
271         assertEquals(new ArrayList<>(fsm.policiesMap.keySet()), cachedStatus.getPolicies());
272
273         factPolicies = controllerSupport.getFacts(ToscaPolicy.class);
274         assertEquals(1, factPolicies.size());
275         assertEquals(toscaPolicyRestartV1, factPolicies.get(0));
276         assertEquals(1, fsm.policiesMap.size());
277
278         // deploy a new version of the operational.restart policy
279
280         ToscaPolicy toscaPolicyRestartV2 =
281             getExamplesPolicy("policies/vCPE.policy.operational.input.tosca.json", "operational.restart");
282         toscaPolicyRestartV2.setVersion("2.0.0");
283         toscaPolicyRestartV2.getProperties().put("controllerName", "lifecycle");
284         update.setPolicies(Collections.singletonList(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());
291
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());
297
298         // deploy another policy : firewall
299
300         ToscaPolicy toscaPolicyFirewall =
301             getExamplesPolicy("policies/vFirewall.policy.operational.input.tosca.json", "operational.modifyconfig");
302         toscaPolicyFirewall.getProperties().put("controllerName", "lifecycle");
303         update.setPolicies(Arrays.asList(toscaPolicyRestartV2, toscaPolicyFirewall));
304         assertTrue(fsm.update(update));
305         assertEquals(qlength + 6, fsm.client.getSink().getRecentEvents().length);
306         assertEquals(3, fsm.policyTypesMap.size());
307         cachedStatus = new StandardCoder()
308             .decode(fsm.client.getSink().getRecentEvents()[qlength + 5], PdpStatus.class);
309         assertEquals(new ArrayList<>(fsm.policiesMap.keySet()), cachedStatus.getPolicies());
310
311         factPolicies = controllerSupport.getFacts(ToscaPolicy.class);
312         assertEquals(2, factPolicies.size());
313         assertTrue(factPolicies.stream().noneMatch((ff) -> Objects.equals(toscaPolicyRestartV1, ff)));
314         assertTrue(factPolicies.stream().anyMatch((ff) -> Objects.equals(toscaPolicyRestartV2, ff)));
315         assertTrue(factPolicies.stream().anyMatch((ff) -> Objects.equals(toscaPolicyFirewall, ff)));
316         assertEquals(2, fsm.policiesMap.size());
317
318         long originalInterval = fsm.getStatusTimerSeconds();
319         long interval = 10 * originalInterval;
320         update.setPdpHeartbeatIntervalMs(interval * 1000L);
321
322         assertTrue(fsm.update(update));
323
324         assertEquals(PdpState.ACTIVE, fsm.state());
325         assertEquals(interval, fsm.getStatusTimerSeconds());
326
327         // bad policy deployment
328
329         String badIntegerPolicy =
330             Files.readString(Paths.get(POLICY_COMPLIANT_VCPE_BAD_INTEGER_JSON), StandardCharsets.UTF_8);
331         ToscaPolicy toscaPolicyRestartBad = new StandardCoder().decode(badIntegerPolicy, ToscaPolicy.class);
332         update.setPolicies(Collections.singletonList(toscaPolicyRestartBad));
333         assertFalse(fsm.update(update));
334
335         assertTrue(controllerSupport.getController().getDrools().delete(ToscaPolicy.class));
336
337         fsm.shutdown();
338     }
339
340 }