0c84419fd8ea0af843cc9fac77074912aaf07832
[policy/xacml-pdp.git] / main / src / test / java / org / onap / policy / pdpx / main / CommonRest.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP
4  * ================================================================================
5  * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  * SPDX-License-Identifier: Apache-2.0
20  * ============LICENSE_END=========================================================
21  */
22
23 package org.onap.policy.pdpx.main;
24
25 import java.io.File;
26 import java.io.IOException;
27 import java.nio.charset.StandardCharsets;
28 import java.nio.file.Files;
29 import java.nio.file.Path;
30 import java.security.SecureRandom;
31 import javax.net.ssl.SSLContext;
32 import javax.ws.rs.client.Client;
33 import javax.ws.rs.client.ClientBuilder;
34 import javax.ws.rs.client.Invocation;
35 import javax.ws.rs.client.WebTarget;
36 import javax.ws.rs.core.MediaType;
37 import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
38 import org.junit.After;
39 import org.junit.AfterClass;
40 import org.junit.Before;
41 import org.junit.BeforeClass;
42 import org.onap.policy.common.utils.network.NetworkUtil;
43 import org.onap.policy.common.utils.resources.ResourceUtils;
44 import org.onap.policy.pdpx.main.rest.XacmlPdpStatisticsManager;
45 import org.onap.policy.pdpx.main.startstop.Main;
46 import org.onap.policy.pdpx.main.startstop.XacmlPdpActivator;
47 import org.powermock.reflect.Whitebox;
48
49 /**
50  * Common base class for REST service tests.
51  */
52 public class CommonRest {
53     private static final String KEYSTORE = System.getProperty("user.dir") + "/src/test/resources/ssl/policy-keystore";
54
55     /**
56      * Full path to the config file.
57      */
58     public static final String CONFIG_FILE;
59
60     /**
61      * Path corresponding to {@link #CONFIG_FILE}.
62      */
63     private static final Path CONFIG_PATH;
64
65     /**
66      * Contents read from the "standard" config file, which still contains ${xxx}
67      * place-holders.
68      */
69     private static final String STD_CONFIG;
70
71     /**
72      * Port that was last allocated for the server.
73      */
74     protected static int port;
75
76     /**
77      * "Main" that was last started.
78      */
79     private static Main main;
80
81     /**
82      * Records the "alive" state of the activator while it's temporarily updated by
83      * various junit tests. The {@link #tearDown()} method restores the "alive" state back
84      * to this value.
85      */
86     private boolean activatorWasAlive;
87
88     static {
89         try {
90             File file = new File(ResourceUtils.getFilePath4Resource("parameters/XacmlPdpConfigParameters_Std.json"));
91             STD_CONFIG = new String(Files.readAllBytes(file.toPath()), StandardCharsets.UTF_8);
92
93             file = new File(file.getParentFile(), "Test_XacmlPdpConfigParameters.json");
94             file.deleteOnExit();
95
96             CONFIG_FILE = file.getAbsolutePath();
97             CONFIG_PATH = new File(CONFIG_FILE).toPath();
98
99         } catch (IOException e) {
100             throw new ExceptionInInitializerError(e);
101         }
102     }
103
104     /**
105      * Configures system properties and creates a JSON config file.
106      *
107      * @throws Exception if an error occurs
108      */
109     @BeforeClass
110     public static void setUpBeforeClass() throws Exception {
111         System.setProperty("javax.net.ssl.keyStore", KEYSTORE);
112         System.setProperty("javax.net.ssl.keyStorePassword", "Pol1cy_0nap");
113
114         System.setProperty("org.eclipse.jetty.util.log.class", "org.eclipse.jetty.util.log.StdErrLog");
115         System.setProperty("org.eclipse.jetty.LEVEL", "OFF");
116
117         writeJsonConfig();
118
119         final String[] xacmlPdpConfigParameters = {"-c", CommonRest.CONFIG_FILE, "-p", "parameters/topic.properties"};
120         main = new Main(xacmlPdpConfigParameters);
121
122         if (!NetworkUtil.isTcpPortOpen("localhost", port, 20, 1000L)) {
123             throw new IllegalStateException("server is not listening on port " + port);
124         }
125     }
126
127     /**
128      * Stops the "Main".
129      */
130     @AfterClass
131     public static void tearDownAfterClass() {
132         stopMain();
133     }
134
135     /**
136      * Resets the statistics.
137      */
138     @Before
139     public void setUp() {
140         activatorWasAlive = XacmlPdpActivator.getCurrent().isAlive();
141         XacmlPdpStatisticsManager.getCurrent().resetAllStatistics();
142     }
143
144     /**
145      * Restores the "alive" status of the activator.
146      */
147     @After
148     public void tearDown() {
149         markActivator(activatorWasAlive);
150     }
151
152     /**
153      * Stops the "main".
154      */
155     protected static void stopMain() {
156         main.shutdown();
157     }
158
159     /**
160      * Writes a JSON config file, substituting an allocated port number for occurrences of
161      * "${port}".
162      *
163      * @return the allocated server port
164      * @throws IOException if the config file cannot be created
165      */
166     public static int writeJsonConfig() throws IOException {
167         port = NetworkUtil.allocPort();
168
169         String config = STD_CONFIG.replace("${port}", String.valueOf(port));
170         Files.write(CONFIG_PATH, config.getBytes(StandardCharsets.UTF_8));
171
172         return port;
173     }
174
175     /**
176      * Sends an HTTPS request to an endpoint of the PDP's REST API.
177      *
178      * @param endpoint target endpoint
179      * @return a request builder
180      * @throws Exception if an error occurs
181      */
182     protected Invocation.Builder sendHttpsRequest(final String endpoint) throws Exception {
183         // always trust the certificate
184         final SSLContext sc = SSLContext.getInstance("TLSv1.2");
185         sc.init(null, NetworkUtil.getAlwaysTrustingManager(), new SecureRandom());
186
187         // always trust the host name
188         final ClientBuilder clientBuilder =
189                         ClientBuilder.newBuilder().sslContext(sc).hostnameVerifier((host, session) -> true);
190
191         final Client client = clientBuilder.build();
192         final HttpAuthenticationFeature feature = HttpAuthenticationFeature.basic("healthcheck", "zb!XztG34");
193         client.register(feature);
194
195         final WebTarget webTarget = client.target("https://localhost:" + port + "/policy/pdpx/v1/" + endpoint);
196
197         return webTarget.request(MediaType.APPLICATION_JSON);
198     }
199
200     /**
201      * Mark the activator as dead, but leave its REST server running.
202      */
203     protected void markActivatorDead() {
204         markActivator(false);
205     }
206
207     /**
208      * Changes the internal "alive" status of the activator to a new value.
209      *
210      * @param newAlive the new "alive" status
211      */
212     private void markActivator(boolean newAlive) {
213         Object manager = Whitebox.getInternalState(XacmlPdpActivator.getCurrent(), "serviceManager");
214         Whitebox.setInternalState(manager, "running", newAlive);
215     }
216 }