Removing deprecated DMAAP library
[policy/drools-pdp.git] / feature-healthcheck / src / test / java / org / onap / policy / drools / healthcheck / HealthCheckFeatureTest.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP
4  * ================================================================================
5  * Copyright (C) 2017-2019,2022 AT&T Intellectual Property. All rights reserved.
6  * Modifications Copyright (C) 2024 Nordix Foundation.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.policy.drools.healthcheck;
23
24 import static org.junit.jupiter.api.Assertions.assertEquals;
25 import static org.junit.jupiter.api.Assertions.assertFalse;
26 import static org.junit.jupiter.api.Assertions.assertTrue;
27 import static org.mockito.ArgumentMatchers.any;
28 import static org.mockito.Mockito.doAnswer;
29 import static org.mockito.Mockito.doThrow;
30 import static org.mockito.Mockito.mock;
31 import static org.mockito.Mockito.never;
32 import static org.mockito.Mockito.spy;
33 import static org.mockito.Mockito.verify;
34 import static org.mockito.Mockito.when;
35
36 import java.io.IOException;
37 import java.nio.file.Paths;
38 import java.util.HashMap;
39 import java.util.List;
40 import java.util.Properties;
41 import org.eclipse.jetty.http.HttpStatus;
42 import org.junit.jupiter.api.AfterAll;
43 import org.junit.jupiter.api.BeforeAll;
44 import org.junit.jupiter.api.Test;
45 import org.kie.api.builder.ReleaseId;
46 import org.mockito.AdditionalAnswers;
47 import org.onap.policy.common.endpoints.http.client.HttpClientFactoryInstance;
48 import org.onap.policy.common.endpoints.http.server.HttpServletServerFactoryInstance;
49 import org.onap.policy.common.utils.logging.LoggerUtils;
50 import org.onap.policy.common.utils.network.NetworkUtil;
51 import org.onap.policy.drools.healthcheck.HealthCheck.Reports;
52 import org.onap.policy.drools.persistence.SystemPersistenceConstants;
53 import org.onap.policy.drools.properties.DroolsPropertyConstants;
54 import org.onap.policy.drools.system.PolicyController;
55 import org.onap.policy.drools.system.PolicyControllerConstants;
56 import org.onap.policy.drools.system.PolicyEngineConstants;
57 import org.onap.policy.drools.util.KieUtils;
58 import org.slf4j.Logger;
59 import org.slf4j.LoggerFactory;
60
61 public class HealthCheckFeatureTest {
62
63     private static final Logger logger = LoggerFactory.getLogger(HealthCheckFeatureTest.class);
64     private static final String EXPECTED = "expected exception";
65
66     /**
67      * Set up.
68      */
69     @BeforeAll
70     public static void setup() throws IOException {
71         SystemPersistenceConstants.getManager().setConfigurationDir("target/test-classes");
72
73         LoggerUtils.setLevel("org.onap.policy.common.endpoints", "WARN");
74         LoggerUtils.setLevel("org.eclipse", "ERROR");
75         LoggerUtils.setLevel("org.onap.policy.drools.healthcheck", "DEBUG");
76         LoggerUtils.setLevel("ROOT", "INFO");
77
78         ReleaseId coords = KieUtils.installArtifact(Paths.get("src/test/resources/echo.kmodule").toFile(),
79             Paths.get("src/test/resources/echo.pom").toFile(),
80             "src/main/resources/kbecho/org/onap/policy/drools/healthcheck/",
81             List.of(Paths.get("src/test/resources/echo.drl").toFile()));
82
83         Properties controllerProps = new Properties();
84         controllerProps.put(DroolsPropertyConstants.PROPERTY_CONTROLLER_NAME, "echo");
85         controllerProps.put(DroolsPropertyConstants.RULES_GROUPID, coords.getGroupId());
86         controllerProps.put(DroolsPropertyConstants.RULES_ARTIFACTID, coords.getArtifactId());
87         controllerProps.put(DroolsPropertyConstants.RULES_VERSION, coords.getVersion());
88
89         PolicyController controller = PolicyControllerConstants.getFactory().build("echo", controllerProps);
90         controller.start();
91     }
92
93     /**
94      * Tear down.
95      */
96     @AfterAll
97     public static void teardown() {
98         PolicyControllerConstants.getFactory().destroy();
99         HttpClientFactoryInstance.getClientFactory().destroy();
100         HttpServletServerFactoryInstance.getServerFactory().destroy();
101     }
102
103     @Test
104     void test() throws InterruptedException {
105         var manager = spy(HealthCheckManager.class);
106         var feature = new HealthCheckFeatureImpl(manager);
107         when(manager.isEngineAlive()).thenReturn(true);
108
109         feature.afterStart(PolicyEngineConstants.getManager());
110         feature.afterOpen(PolicyEngineConstants.getManager());
111
112         checkOpen(7777);
113         checkOpen(7776);
114
115         var reports = healthcheck(manager);
116         serverChecks(reports);
117         checkReports(reports, List.of("STUCK"),
118                 HttpStatus.OK_200, HttpStatus.getMessage(200));
119         checkReports(reports, List.of("echo"), 1, "[echo:{java.lang.String=1}]");
120
121         /* mock controller and clients stuck */
122
123         RestMockHealthCheck.stuck = true;   // make the server named STUCK unresponsive
124         doAnswer(AdditionalAnswers
125                 .answersWithDelay((manager.getTimeoutSeconds() + 2) * 1000L,
126                         invocationOnMock -> new HashMap<String, Integer>()))
127                 .when(manager).getFactTypes(any(), any());
128
129         reports = healthcheck(manager);
130         RestMockHealthCheck.stuck = false;  // unstuck the server named STUCK
131
132         serverChecks(reports);
133         checkReports(reports, List.of("STUCK"),
134                 HealthCheckManager.TIMEOUT_CODE, HealthCheckManager.TIMEOUT_MESSAGE);
135
136         assertTrue(RestMockHealthCheck.WAIT * 1000 > HealthCheckManagerTest.select(reports, "STUCK",
137                         HealthCheckManager.TIMEOUT_CODE, HealthCheckManager.TIMEOUT_MESSAGE)
138                 .get(0).getElapsedTime());
139
140         feature.afterShutdown(PolicyEngineConstants.getManager());
141     }
142
143     private void checkReports(Reports reports, List<String> reportNames, int code, String message) {
144         reportNames
145                 .forEach(name -> assertEquals(1,
146                         HealthCheckManagerTest.select(reports, name, code, message).size()));
147     }
148
149     private Reports healthcheck(HealthCheck manager) {
150         var reports = manager.healthCheck();
151         logger.info("{}", reports);
152         return reports;
153     }
154
155     private void checkOpen(int port) throws InterruptedException {
156         if (!NetworkUtil.isTcpPortOpen("localhost", port, 5, 10000L)) {
157             throw new IllegalStateException("cannot connect to port " + port);
158         }
159     }
160
161     private void serverChecks(Reports reports) {
162         checkReports(reports, List.of("HEALTHCHECK", "LIVENESS"),
163                 HttpStatus.OK_200, HttpStatus.getMessage(200));
164         checkReports(reports, List.of("UNAUTH"),
165                 HttpStatus.UNAUTHORIZED_401, HttpStatus.getMessage(401));
166         checkReports(reports, List.of(HealthCheckManager.ENGINE_NAME),
167                 HealthCheckManager.SUCCESS_CODE, HealthCheckManager.ENABLED_MESSAGE);
168     }
169
170     @Test
171     void testGetSequenceNumber() {
172         assertEquals(1000, new HealthCheckFeature().getSequenceNumber());
173     }
174
175     @Test
176     void testAfterStart() {
177         HealthCheck checker = mock(HealthCheck.class);
178         HealthCheckFeature feature = new HealthCheckFeatureImpl(checker);
179
180         // without exception
181         assertFalse(feature.afterStart(null));
182         verify(checker).start();
183         verify(checker, never()).stop();
184
185         // with exception
186         doThrow(new IllegalStateException(EXPECTED)).when(checker).start();
187         assertFalse(feature.afterStart(null));
188     }
189
190     @Test
191     void testAfterOpen() {
192         HealthCheck checker = mock(HealthCheck.class);
193         HealthCheckFeature feature = new HealthCheckFeatureImpl(checker);
194
195         // without exception
196         assertFalse(feature.afterOpen(null));
197         verify(checker).open();
198         verify(checker, never()).stop();
199
200         // with exception
201         doThrow(new IllegalStateException(EXPECTED)).when(checker).open();
202         assertFalse(feature.afterOpen(null));
203
204     }
205
206     @Test
207     void testAfterShutdown() {
208         HealthCheck checker = mock(HealthCheck.class);
209         HealthCheckFeature feature = new HealthCheckFeatureImpl(checker);
210
211         // without exception
212         assertFalse(feature.afterShutdown(null));
213         verify(checker).stop();
214         verify(checker, never()).start();
215
216         // with exception
217         doThrow(new IllegalStateException(EXPECTED)).when(checker).stop();
218         assertFalse(feature.afterShutdown(null));
219     }
220
221     /**
222      * Feature that returns a particular monitor.
223      */
224     private static class HealthCheckFeatureImpl extends HealthCheckFeature {
225         private final HealthCheck checker;
226
227         public HealthCheckFeatureImpl(HealthCheck checker) {
228             this.checker = checker;
229         }
230
231         @Override
232         public HealthCheck getManager() {
233             return checker;
234         }
235
236     }
237 }