2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017-2020 AT&T Intellectual Property. All rights reserved.
6 * Modifications Copyright (C) 2020 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
12 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
22 package org.onap.policy.common.endpoints.http.server.test;
24 import static org.assertj.core.api.Assertions.assertThat;
25 import static org.assertj.core.api.Assertions.assertThatCode;
26 import static org.assertj.core.api.Assertions.assertThatThrownBy;
27 import static org.assertj.core.api.Assertions.catchThrowable;
28 import static org.junit.Assert.assertEquals;
29 import static org.junit.Assert.assertFalse;
30 import static org.junit.Assert.assertNotNull;
31 import static org.junit.Assert.assertTrue;
33 import com.google.gson.Gson;
34 import java.io.IOException;
35 import java.io.InputStream;
36 import java.net.HttpURLConnection;
37 import java.net.MalformedURLException;
39 import java.net.URLConnection;
40 import java.nio.charset.StandardCharsets;
41 import java.util.UUID;
42 import org.apache.commons.io.IOUtils;
43 import org.junit.AfterClass;
44 import org.junit.Before;
45 import org.junit.Test;
46 import org.onap.policy.common.endpoints.http.server.HttpServletServer;
47 import org.onap.policy.common.endpoints.http.server.HttpServletServerFactoryInstance;
48 import org.onap.policy.common.endpoints.http.server.YamlMessageBodyHandler;
49 import org.onap.policy.common.utils.coder.StandardYamlCoder;
50 import org.onap.policy.common.utils.gson.GsonTestUtils;
51 import org.onap.policy.common.utils.network.NetworkUtil;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
56 * HttpServletServer JUNIT tests.
58 public class HttpServerTest {
59 private static final String LOCALHOST = "localhost";
60 private static final String JSON_MEDIA = "application/json";
61 private static final String YAML_MEDIA = YamlMessageBodyHandler.APPLICATION_YAML;
62 private static final String SWAGGER_JSON = "/swagger.json";
63 private static final String JUNIT_ECHO_HELLO = "/junit/echo/hello";
64 private static final String JUNIT_ECHO_FULL_REQUEST = "/junit/echo/full/request";
65 private static final String SOME_TEXT = "some text";
66 private static final String HELLO = "hello";
71 private static Logger logger = LoggerFactory.getLogger(HttpServerTest.class);
73 private static final String LOCALHOST_PREFIX = "http://localhost:";
75 private static final Gson gson = new Gson();
78 * Server port. Incremented by 10 with each test.
80 private static int port = 5608;
82 private String portUrl;
85 * Increments the port number, clears the servers, and resets the providers.
90 portUrl = LOCALHOST_PREFIX + port;
92 HttpServletServerFactoryInstance.getServerFactory().destroy();
94 MyGsonProvider.resetSome();
95 MyYamlProvider.resetSome();
98 private static void incrementPort() {
103 * To delete temporary properties cadi_longitude,and cadi_latitude.
106 public static void tearDownAfterClass() {
107 HttpServletServerFactoryInstance.getServerFactory().destroy();
108 System.clearProperty("cadi_longitude");
109 System.clearProperty("cadi_latitude");
113 public void testDefaultPackageServer() throws Exception {
114 logger.info("-- testDefaultPackageServer() --");
116 HttpServletServer server = HttpServletServerFactoryInstance.getServerFactory()
117 .build("echo", LOCALHOST, port, "/", false, true);
118 server.addServletPackage("/*", this.getClass().getPackage().getName());
119 server.addFilterClass("/*", TestFilter.class.getName());
120 server.waitedStart(5000);
122 assertTrue(HttpServletServerFactoryInstance.getServerFactory().get(port).isAlive());
124 RestEchoReqResp request = new RestEchoReqResp();
125 request.setRequestId(100);
126 request.setText(SOME_TEXT);
127 String reqText = gson.toJson(request);
129 String response = http(portUrl + JUNIT_ECHO_FULL_REQUEST, JSON_MEDIA, reqText);
130 assertEquals(reqText, response);
134 public void testGsonPackageServer() throws Exception {
135 logger.info("-- testGsonPackageServer() --");
137 HttpServletServer server = HttpServletServerFactoryInstance.getServerFactory()
138 .build("echo", LOCALHOST, port, "/", false, true);
140 server.setSerializationProvider(MyGsonProvider.class.getName());
141 server.addServletPackage("/*", this.getClass().getPackage().getName());
142 server.addFilterClass("/*", TestFilter.class.getName());
143 server.waitedStart(5000);
145 assertTrue(HttpServletServerFactoryInstance.getServerFactory().get(port).isAlive());
147 RestEchoReqResp request = new RestEchoReqResp();
148 request.setRequestId(100);
149 request.setText(SOME_TEXT);
150 String reqText = gson.toJson(request);
152 String response = http(portUrl + JUNIT_ECHO_FULL_REQUEST, JSON_MEDIA, reqText);
153 assertEquals(reqText, response);
155 assertTrue(MyGsonProvider.hasReadSome());
156 assertTrue(MyGsonProvider.hasWrittenSome());
158 assertFalse(MyYamlProvider.hasReadSome());
159 assertFalse(MyYamlProvider.hasWrittenSome());
163 public void testYamlPackageServer() throws Exception {
164 logger.info("-- testYamlPackageServer() --");
166 HttpServletServer server = HttpServletServerFactoryInstance.getServerFactory()
167 .build("echo", LOCALHOST, port, "/", false, true);
169 server.setSerializationProvider(MyYamlProvider.class.getName());
170 server.addServletPackage("/*", this.getClass().getPackage().getName());
171 server.addFilterClass("/*", TestFilter.class.getName());
172 server.waitedStart(5000);
174 assertTrue(HttpServletServerFactoryInstance.getServerFactory().get(port).isAlive());
176 RestEchoReqResp request = new RestEchoReqResp();
177 request.setRequestId(100);
178 request.setText(SOME_TEXT);
179 String reqText = new StandardYamlCoder().encode(request);
181 String response = http(portUrl + JUNIT_ECHO_FULL_REQUEST, YAML_MEDIA, reqText);
183 // response reader strips newlines, so we should, too, before comparing
184 assertEquals(reqText.replace("\n", ""), response);
186 assertTrue(MyYamlProvider.hasReadSome());
187 assertTrue(MyYamlProvider.hasWrittenSome());
189 assertFalse(MyGsonProvider.hasReadSome());
190 assertFalse(MyGsonProvider.hasWrittenSome());
194 public void testDefaultClassServer() throws Exception {
195 logger.info("-- testDefaultClassServer() --");
197 HttpServletServer server = HttpServletServerFactoryInstance.getServerFactory()
198 .build("echo", LOCALHOST, port, "/", false, true);
199 server.addServletClass("/*", RestEchoService.class.getName());
200 server.addFilterClass("/*", TestFilter.class.getName());
201 server.waitedStart(5000);
203 assertTrue(HttpServletServerFactoryInstance.getServerFactory().get(port).isAlive());
205 RestEchoReqResp request = new RestEchoReqResp();
206 request.setRequestId(100);
207 request.setText(SOME_TEXT);
208 String reqText = gson.toJson(request);
210 String response = http(portUrl + JUNIT_ECHO_FULL_REQUEST, JSON_MEDIA, reqText);
211 assertEquals(reqText, response);
215 public void testJacksonClassServer() throws Exception {
216 logger.info("-- testJacksonClassServer() --");
218 HttpServletServer server = HttpServletServerFactoryInstance.getServerFactory()
219 .build("echo", LOCALHOST, port, "/", false, true);
220 server.addServletClass("/*", RestEchoService.class.getName());
221 server.addFilterClass("/*", TestFilter.class.getName());
222 server.waitedStart(5000);
224 assertTrue(HttpServletServerFactoryInstance.getServerFactory().get(port).isAlive());
226 RestEchoReqResp request = new RestEchoReqResp();
227 request.setRequestId(100);
228 request.setText(SOME_TEXT);
229 String reqText = gson.toJson(request);
231 String response = http(portUrl + JUNIT_ECHO_FULL_REQUEST, JSON_MEDIA, reqText);
232 assertEquals(reqText, response);
234 assertFalse(MyGsonProvider.hasReadSome());
235 assertFalse(MyGsonProvider.hasWrittenSome());
237 assertFalse(MyYamlProvider.hasReadSome());
238 assertFalse(MyYamlProvider.hasWrittenSome());
242 public void testGsonClassServer() throws Exception {
243 logger.info("-- testGsonClassServer() --");
245 HttpServletServer server = HttpServletServerFactoryInstance.getServerFactory()
246 .build("echo", LOCALHOST, port, "/", false, true);
247 server.setSerializationProvider(MyGsonProvider.class.getName());
248 server.addServletClass("/*", RestEchoService.class.getName());
249 server.addFilterClass("/*", TestFilter.class.getName());
250 server.waitedStart(5000);
252 assertTrue(HttpServletServerFactoryInstance.getServerFactory().get(port).isAlive());
254 RestEchoReqResp request = new RestEchoReqResp();
255 request.setRequestId(100);
256 request.setText(SOME_TEXT);
257 String reqText = gson.toJson(request);
259 String response = http(portUrl + JUNIT_ECHO_FULL_REQUEST, JSON_MEDIA, reqText);
260 assertEquals(reqText, response);
262 assertTrue(MyGsonProvider.hasReadSome());
263 assertTrue(MyGsonProvider.hasWrittenSome());
265 assertFalse(MyYamlProvider.hasReadSome());
266 assertFalse(MyYamlProvider.hasWrittenSome());
270 public void testYamlClassServer() throws Exception {
271 logger.info("-- testYamlClassServer() --");
273 HttpServletServer server = HttpServletServerFactoryInstance.getServerFactory()
274 .build("echo", LOCALHOST, port, "/", false, true);
275 server.setSerializationProvider(MyYamlProvider.class.getName());
276 server.addServletClass("/*", RestEchoService.class.getName());
277 server.addFilterClass("/*", TestFilter.class.getName());
278 server.waitedStart(5000);
280 assertTrue(HttpServletServerFactoryInstance.getServerFactory().get(port).isAlive());
282 RestEchoReqResp request = new RestEchoReqResp();
283 request.setRequestId(100);
284 request.setText(SOME_TEXT);
285 String reqText = new StandardYamlCoder().encode(request);
287 String response = http(portUrl + JUNIT_ECHO_FULL_REQUEST, YAML_MEDIA, reqText);
289 // response reader strips newlines, so we should, too, before comparing
290 assertEquals(reqText.replace("\n", ""), response);
292 assertTrue(MyYamlProvider.hasReadSome());
293 assertTrue(MyYamlProvider.hasWrittenSome());
295 assertFalse(MyGsonProvider.hasReadSome());
296 assertFalse(MyGsonProvider.hasWrittenSome());
300 public void testSerialize() {
301 HttpServletServer server = HttpServletServerFactoryInstance.getServerFactory()
302 .build("echo", LOCALHOST, port, "/", false, true);
303 server.addServletPackage("/*", this.getClass().getPackage().getName());
304 server.addFilterClass("/*", TestFilter.class.getName());
306 // ensure we can serialize the server
307 assertThatCode(() -> new GsonTestUtils().compareGson(server, HttpServerTest.class)).doesNotThrowAnyException();
311 public void testSingleServer() throws Exception {
312 logger.info("-- testSingleServer() --");
314 HttpServletServer server = HttpServletServerFactoryInstance.getServerFactory()
315 .build("echo", LOCALHOST, port, "/", false, true);
316 server.addServletPackage("/*", this.getClass().getPackage().getName());
317 server.addFilterClass("/*", TestFilter.class.getName());
318 server.waitedStart(5000);
320 assertTrue(HttpServletServerFactoryInstance.getServerFactory().get(port).isAlive());
321 assertFalse(HttpServletServerFactoryInstance.getServerFactory().get(port).isAaf());
323 String response = http(portUrl + JUNIT_ECHO_HELLO);
324 assertEquals(HELLO, response);
326 assertThatThrownBy(() -> http(portUrl + SWAGGER_JSON)).isInstanceOf(IOException.class);
328 response = http(portUrl + "/junit/echo/hello?block=true");
329 assertEquals("FILTERED", response);
331 assertTrue(HttpServletServerFactoryInstance.getServerFactory().get(port).isAlive());
332 assertEquals(1, HttpServletServerFactoryInstance.getServerFactory().inventory().size());
334 System.setProperty("cadi_longitude", "0.0");
335 System.setProperty("cadi_latitude", "0.0");
336 server.setAafAuthentication("/*");
337 assertTrue(HttpServletServerFactoryInstance.getServerFactory().get(port).isAaf());
339 HttpServletServerFactoryInstance.getServerFactory().destroy(port);
340 assertEquals(0, HttpServletServerFactoryInstance.getServerFactory().inventory().size());
344 public void testMultipleServers() throws Exception {
345 logger.info("-- testMultipleServers() --");
347 HttpServletServer server1 = HttpServletServerFactoryInstance.getServerFactory()
348 .build("echo-1", false, LOCALHOST, port, "/", true, true);
349 server1.addServletPackage("/*", this.getClass().getPackage().getName());
350 server1.waitedStart(5000);
352 int port2 = port + 1;
354 HttpServletServer server2 = HttpServletServerFactoryInstance.getServerFactory()
355 .build("echo-2", LOCALHOST, port2, "/", false, true);
356 server2.addServletPackage("/*", this.getClass().getPackage().getName());
357 server2.waitedStart(5000);
359 assertTrue(HttpServletServerFactoryInstance.getServerFactory().get(port).isAlive());
360 assertTrue(HttpServletServerFactoryInstance.getServerFactory().get(port2).isAlive());
362 String response = http(portUrl + JUNIT_ECHO_HELLO);
363 assertEquals(HELLO, response);
365 response = http(portUrl + SWAGGER_JSON);
366 assertNotNull(response);
368 response = http(LOCALHOST_PREFIX + port2 + JUNIT_ECHO_HELLO);
369 assertEquals(HELLO, response);
371 assertThatThrownBy(() -> http(LOCALHOST_PREFIX + port2 + SWAGGER_JSON)).isInstanceOf(IOException.class);
373 HttpServletServerFactoryInstance.getServerFactory().destroy();
374 assertTrue(HttpServletServerFactoryInstance.getServerFactory().inventory().isEmpty());
378 public void testMultiServicePackage() throws Exception {
379 logger.info("-- testMultiServicePackage() --");
381 String randomName = UUID.randomUUID().toString();
383 HttpServletServer server = HttpServletServerFactoryInstance.getServerFactory()
384 .build(randomName, LOCALHOST, port, "/", false, true);
385 server.addServletPackage("/*", this.getClass().getPackage().getName());
386 server.waitedStart(5000);
388 assertTrue(HttpServletServerFactoryInstance.getServerFactory().get(port).isAlive());
390 String response = http(portUrl + JUNIT_ECHO_HELLO);
391 assertEquals(HELLO, response);
393 response = http(portUrl + "/junit/endpoints/http/servers");
394 assertTrue(response.contains(randomName));
396 HttpServletServerFactoryInstance.getServerFactory().destroy();
397 assertTrue(HttpServletServerFactoryInstance.getServerFactory().inventory().isEmpty());
401 public void testServiceClass() throws Exception {
402 logger.info("-- testServiceClass() --");
403 String randomName = UUID.randomUUID().toString();
405 HttpServletServer server = HttpServletServerFactoryInstance.getServerFactory()
406 .build(randomName, LOCALHOST, port, "/", false, true);
407 server.addServletClass("/*", RestEchoService.class.getName());
408 server.waitedStart(5000);
410 assertTrue(HttpServletServerFactoryInstance.getServerFactory().get(port).isAlive());
412 String response = http(portUrl + JUNIT_ECHO_HELLO);
413 assertEquals(HELLO, response);
415 HttpServletServerFactoryInstance.getServerFactory().destroy();
416 assertTrue(HttpServletServerFactoryInstance.getServerFactory().inventory().isEmpty());
420 public void testMultiServiceClass() throws Exception {
421 logger.info("-- testMultiServiceClass() --");
423 String randomName = UUID.randomUUID().toString();
425 HttpServletServer server = HttpServletServerFactoryInstance.getServerFactory()
426 .build(randomName, LOCALHOST, port, "/", false, true);
427 server.addServletClass("/*", RestEchoService.class.getName());
428 server.addServletClass("/*", RestEndpoints.class.getName());
429 server.waitedStart(5000);
431 assertTrue(HttpServletServerFactoryInstance.getServerFactory().get(port).isAlive());
433 String response = http(portUrl + JUNIT_ECHO_HELLO);
434 assertEquals(HELLO, response);
436 response = http(portUrl + "/junit/endpoints/http/servers");
437 assertTrue(response.contains(randomName));
439 HttpServletServerFactoryInstance.getServerFactory().destroy();
440 assertTrue(HttpServletServerFactoryInstance.getServerFactory().inventory().isEmpty());
444 public void testSingleStaticResourceServer() throws Exception {
445 logger.info("-- testSingleStaticResourceServer() --");
447 HttpServletServer staticServer = HttpServletServerFactoryInstance.getServerFactory()
448 .buildStaticResourceServer("Static Resources Server", false, LOCALHOST, port, "/", true);
449 Throwable thrown = catchThrowable(() -> staticServer.addServletResource("/*", null));
450 assertThat(thrown).isInstanceOf(IllegalArgumentException.class)
451 .hasMessageContaining("No resourceBase provided");
453 staticServer.addServletResource(null,
454 HttpServerTest.class.getClassLoader().getResource("webapps/root").toExternalForm());
456 thrown = catchThrowable(() -> staticServer.addServletClass("/*", RestEchoService.class.getName()));
457 assertThat(thrown).isInstanceOf(UnsupportedOperationException.class)
458 .hasMessageContaining("is not supported on this type of jetty server");
460 thrown = catchThrowable(() -> staticServer.addServletPackage("/api/*", this.getClass().getPackage().getName()));
461 assertThat(thrown).isInstanceOf(UnsupportedOperationException.class)
462 .hasMessageContaining("is not supported on this type of jetty server");
464 thrown = catchThrowable(() -> staticServer.setSerializationProvider(MyGsonProvider.class.getName()));
465 assertThat(thrown).isInstanceOf(UnsupportedOperationException.class)
466 .hasMessageContaining("is not supported on this type of jetty server");
468 staticServer.waitedStart(5000);
470 assertTrue(HttpServletServerFactoryInstance.getServerFactory().get(port).isAlive());
471 assertEquals(1, HttpServletServerFactoryInstance.getServerFactory().inventory().size());
473 String response = http(portUrl);
474 assertThat(response).contains("Test Jetty Static Resources Root");
476 HttpServletServerFactoryInstance.getServerFactory().destroy(port);
477 assertEquals(0, HttpServletServerFactoryInstance.getServerFactory().inventory().size());
481 public void testMultiStaticResourceServer() throws Exception {
482 logger.info("-- testMultiStaticResourceServer() --");
484 HttpServletServer staticResourceServer = HttpServletServerFactoryInstance.getServerFactory()
485 .buildStaticResourceServer("Static Resources Server", false, LOCALHOST, port, "/", true);
486 staticResourceServer.addServletResource("/root/*",
487 HttpServerTest.class.getClassLoader().getResource("webapps/root").toExternalForm());
488 staticResourceServer.addServletResource("/alt-root/*",
489 HttpServerTest.class.getClassLoader().getResource("webapps/alt-root").toExternalForm());
490 staticResourceServer.waitedStart(5000);
492 assertTrue(HttpServletServerFactoryInstance.getServerFactory().get(port).isAlive());
493 assertEquals(1, HttpServletServerFactoryInstance.getServerFactory().inventory().size());
495 String response = http(portUrl + "/root/");
496 assertThat(response).contains("Test Jetty Static Resources Root");
498 response = http(portUrl + "/alt-root/");
499 assertThat(response).contains("Test Jetty Static Resources Alt-Root");
501 HttpServletServerFactoryInstance.getServerFactory().destroy(port);
502 assertEquals(0, HttpServletServerFactoryInstance.getServerFactory().inventory().size());
506 public void testMultiTypesServer() throws Exception {
507 logger.info("-- testMultiTypesServer() --");
509 HttpServletServer staticResourceServer = HttpServletServerFactoryInstance.getServerFactory()
510 .buildStaticResourceServer("Static Resources Server", false, LOCALHOST, port, "/", true);
511 staticResourceServer.addServletResource("/root/*",
512 HttpServerTest.class.getClassLoader().getResource("webapps/root").toExternalForm());
513 staticResourceServer.waitedStart(5000);
515 int port2 = port + 1;
516 HttpServletServer jerseyServer =
517 HttpServletServerFactoryInstance.getServerFactory().build("echo", LOCALHOST, port2, "/", false, true);
518 jerseyServer.addServletPackage("/api/*", this.getClass().getPackage().getName());
520 Throwable thrown = catchThrowable(() -> jerseyServer.addServletResource("/root/*",
521 HttpServerTest.class.getClassLoader().getResource("webapps/root").toExternalForm()));
522 assertThat(thrown).isInstanceOf(UnsupportedOperationException.class)
523 .hasMessageContaining("is not supported on this type of jetty server");
525 jerseyServer.waitedStart(5000);
527 assertTrue(HttpServletServerFactoryInstance.getServerFactory().get(port).isAlive());
528 assertEquals(2, HttpServletServerFactoryInstance.getServerFactory().inventory().size());
530 String response = http(portUrl + "/root/");
531 assertThat(response).contains("Test Jetty Static Resources Root");
533 response = http(LOCALHOST_PREFIX + port2 + "/api" + JUNIT_ECHO_HELLO);
534 assertEquals(HELLO, response);
536 HttpServletServerFactoryInstance.getServerFactory().destroy();
537 assertEquals(0, HttpServletServerFactoryInstance.getServerFactory().inventory().size());
541 * performs an http request.
543 * @throws MalformedURLException make sure URL is good
544 * @throws IOException thrown is IO exception occurs
545 * @throws InterruptedException thrown if thread interrupted occurs
547 private String http(String urlString)
548 throws IOException, InterruptedException {
549 URL url = new URL(urlString);
550 if (!NetworkUtil.isTcpPortOpen(url.getHost(), url.getPort(), 25, 100)) {
551 throw new IllegalStateException("port never opened: " + url);
553 return response(url.openConnection());
557 * Performs an http request.
559 * @throws MalformedURLException make sure URL is good
560 * @throws IOException thrown is IO exception occurs
561 * @throws InterruptedException thrown if thread interrupted occurs
563 private String http(String urlString, String mediaType, String post)
564 throws IOException, InterruptedException {
565 URL url = new URL(urlString);
566 if (!NetworkUtil.isTcpPortOpen(url.getHost(), url.getPort(), 25, 100)) {
567 throw new IllegalStateException("port never opened: " + url);
569 HttpURLConnection conn = (HttpURLConnection) url.openConnection();
570 conn.setRequestMethod("POST");
571 conn.setDoOutput(true);
572 conn.setRequestProperty("Content-Type", mediaType);
573 conn.setRequestProperty("Accept", mediaType);
574 IOUtils.write(post, conn.getOutputStream(), StandardCharsets.UTF_8);
575 return response(conn);
579 * gets http response.
581 * @param conn connection from which to read
583 * @throws IOException if an I/O error occurs
585 private String response(URLConnection conn) throws IOException {
586 try (InputStream inpstr = conn.getInputStream()) {
587 return String.join("", IOUtils.readLines(inpstr, StandardCharsets.UTF_8));