0aec411b3e4b338f8e35914838c0780a5923fb08
[policy/common.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP
4  * ================================================================================
5  * Copyright (C) 2017-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  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.common.endpoints.http.server.test;
22
23 import static org.assertj.core.api.Assertions.assertThatThrownBy;
24 import static org.junit.Assert.assertEquals;
25 import static org.junit.Assert.assertFalse;
26 import static org.junit.Assert.assertTrue;
27
28 import com.google.gson.Gson;
29 import java.io.IOException;
30 import java.io.InputStream;
31 import java.net.HttpURLConnection;
32 import java.net.MalformedURLException;
33 import java.net.URL;
34 import java.net.URLConnection;
35 import java.util.UUID;
36 import org.apache.commons.io.IOUtils;
37 import org.junit.AfterClass;
38 import org.junit.Before;
39 import org.junit.Test;
40 import org.onap.policy.common.endpoints.http.server.HttpServletServer;
41 import org.onap.policy.common.endpoints.http.server.HttpServletServerFactoryInstance;
42 import org.onap.policy.common.endpoints.http.server.YamlMessageBodyHandler;
43 import org.onap.policy.common.utils.coder.StandardYamlCoder;
44 import org.onap.policy.common.utils.gson.GsonTestUtils;
45 import org.onap.policy.common.utils.network.NetworkUtil;
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
48
49 /**
50  * HttpServletServer JUNIT tests.
51  */
52 public class HttpServerTest {
53     private static final String LOCALHOST = "localhost";
54     private static final String JSON_MEDIA = "application/json";
55     private static final String YAML_MEDIA = YamlMessageBodyHandler.APPLICATION_YAML;
56     private static final String SWAGGER_JSON = "/swagger.json";
57     private static final String JUNIT_ECHO_HELLO = "/junit/echo/hello";
58     private static final String JUNIT_ECHO_FULL_REQUEST = "/junit/echo/full/request";
59     private static final String SOME_TEXT = "some text";
60     private static final String HELLO = "hello";
61
62     /**
63      * Logger.
64      */
65     private static Logger logger = LoggerFactory.getLogger(HttpServerTest.class);
66
67     private static final String LOCALHOST_PREFIX = "http://localhost:";
68
69     private static final Gson gson = new Gson();
70
71     /**
72      * Server port.  Incremented by 10 with each test.
73      */
74     private static int port = 5608;
75
76     private String portUrl;
77
78     /**
79      * Increments the port number, clears the servers, and resets the providers.
80      */
81     @Before
82     public void setUp() {
83         incrementPort();
84         portUrl = LOCALHOST_PREFIX + port;
85
86         HttpServletServerFactoryInstance.getServerFactory().destroy();
87
88         MyJacksonProvider.resetSome();
89         MyGsonProvider.resetSome();
90         MyYamlProvider.resetSome();
91     }
92
93     private static void incrementPort() {
94         port += 10;
95     }
96
97     @AfterClass
98     public static void tearDownAfterClass() {
99         HttpServletServerFactoryInstance.getServerFactory().destroy();
100     }
101
102     @Test
103     public void testDefaultPackageServer() throws Exception {
104         logger.info("-- testDefaultPackageServer() --");
105
106         HttpServletServer server = HttpServletServerFactoryInstance.getServerFactory()
107                         .build("echo", LOCALHOST, port, "/", false, true);
108         server.addServletPackage("/*", this.getClass().getPackage().getName());
109         server.addFilterClass("/*", TestFilter.class.getName());
110         server.waitedStart(5000);
111
112         assertTrue(HttpServletServerFactoryInstance.getServerFactory().get(port).isAlive());
113
114         RestEchoReqResp request = new RestEchoReqResp();
115         request.setRequestId(100);
116         request.setText(SOME_TEXT);
117         String reqText = gson.toJson(request);
118
119         String response = http(portUrl + JUNIT_ECHO_FULL_REQUEST, JSON_MEDIA, reqText);
120         assertEquals(reqText, response);
121     }
122
123     @Test
124     public void testJacksonPackageServer() throws Exception {
125         logger.info("-- testJacksonPackageServer() --");
126
127         HttpServletServer server = HttpServletServerFactoryInstance.getServerFactory()
128                         .build("echo", LOCALHOST, port, "/", false, true);
129
130         server.setSerializationProvider(MyJacksonProvider.class.getName());
131         server.addServletPackage("/*", this.getClass().getPackage().getName());
132         server.addFilterClass("/*", TestFilter.class.getName());
133         server.waitedStart(5000);
134
135         assertTrue(HttpServletServerFactoryInstance.getServerFactory().get(port).isAlive());
136
137         RestEchoReqResp request = new RestEchoReqResp();
138         request.setRequestId(100);
139         request.setText(SOME_TEXT);
140         String reqText = gson.toJson(request);
141
142         String response = http(portUrl + JUNIT_ECHO_FULL_REQUEST, JSON_MEDIA, reqText);
143         assertEquals(reqText, response);
144
145         assertTrue(MyJacksonProvider.hasReadSome());
146         assertTrue(MyJacksonProvider.hasWrittenSome());
147
148         assertFalse(MyGsonProvider.hasReadSome());
149         assertFalse(MyGsonProvider.hasWrittenSome());
150
151         assertFalse(MyYamlProvider.hasReadSome());
152         assertFalse(MyYamlProvider.hasWrittenSome());
153     }
154
155     @Test
156     public void testGsonPackageServer() throws Exception {
157         logger.info("-- testGsonPackageServer() --");
158
159         HttpServletServer server = HttpServletServerFactoryInstance.getServerFactory()
160                         .build("echo", LOCALHOST, port, "/", false, true);
161
162         server.setSerializationProvider(MyGsonProvider.class.getName());
163         server.addServletPackage("/*", this.getClass().getPackage().getName());
164         server.addFilterClass("/*", TestFilter.class.getName());
165         server.waitedStart(5000);
166
167         assertTrue(HttpServletServerFactoryInstance.getServerFactory().get(port).isAlive());
168
169         RestEchoReqResp request = new RestEchoReqResp();
170         request.setRequestId(100);
171         request.setText(SOME_TEXT);
172         String reqText = gson.toJson(request);
173
174         String response = http(portUrl + JUNIT_ECHO_FULL_REQUEST, JSON_MEDIA, reqText);
175         assertEquals(reqText, response);
176
177         assertTrue(MyGsonProvider.hasReadSome());
178         assertTrue(MyGsonProvider.hasWrittenSome());
179
180         assertFalse(MyJacksonProvider.hasReadSome());
181         assertFalse(MyJacksonProvider.hasWrittenSome());
182
183         assertFalse(MyYamlProvider.hasReadSome());
184         assertFalse(MyYamlProvider.hasWrittenSome());
185     }
186
187     @Test
188     public void testYamlPackageServer() throws Exception {
189         logger.info("-- testYamlPackageServer() --");
190
191         HttpServletServer server = HttpServletServerFactoryInstance.getServerFactory()
192                         .build("echo", LOCALHOST, port, "/", false, true);
193
194         server.setSerializationProvider(MyYamlProvider.class.getName());
195         server.addServletPackage("/*", this.getClass().getPackage().getName());
196         server.addFilterClass("/*", TestFilter.class.getName());
197         server.waitedStart(5000);
198
199         assertTrue(HttpServletServerFactoryInstance.getServerFactory().get(port).isAlive());
200
201         RestEchoReqResp request = new RestEchoReqResp();
202         request.setRequestId(100);
203         request.setText(SOME_TEXT);
204         String reqText = new StandardYamlCoder().encode(request);
205
206         String response = http(portUrl + JUNIT_ECHO_FULL_REQUEST, YAML_MEDIA, reqText);
207
208         // response reader strips newlines, so we should, too, before comparing
209         assertEquals(reqText.replace("\n", ""), response);
210
211         assertTrue(MyYamlProvider.hasReadSome());
212         assertTrue(MyYamlProvider.hasWrittenSome());
213
214         assertFalse(MyGsonProvider.hasReadSome());
215         assertFalse(MyGsonProvider.hasWrittenSome());
216
217         assertFalse(MyJacksonProvider.hasReadSome());
218         assertFalse(MyJacksonProvider.hasWrittenSome());
219     }
220
221     @Test
222     public void testDefaultClassServer() throws Exception {
223         logger.info("-- testDefaultClassServer() --");
224
225         HttpServletServer server = HttpServletServerFactoryInstance.getServerFactory()
226                         .build("echo", LOCALHOST, port, "/", false, true);
227         server.addServletClass("/*", RestEchoService.class.getName());
228         server.addFilterClass("/*", TestFilter.class.getName());
229         server.waitedStart(5000);
230
231         assertTrue(HttpServletServerFactoryInstance.getServerFactory().get(port).isAlive());
232
233         RestEchoReqResp request = new RestEchoReqResp();
234         request.setRequestId(100);
235         request.setText(SOME_TEXT);
236         String reqText = gson.toJson(request);
237
238         String response = http(portUrl + JUNIT_ECHO_FULL_REQUEST, JSON_MEDIA, reqText);
239         assertEquals(reqText, response);
240     }
241
242     @Test
243     public void testJacksonClassServer() throws Exception {
244         logger.info("-- testJacksonClassServer() --");
245
246         HttpServletServer server = HttpServletServerFactoryInstance.getServerFactory()
247                         .build("echo", LOCALHOST, port, "/", false, true);
248         server.setSerializationProvider(MyJacksonProvider.class.getName());
249         server.addServletClass("/*", RestEchoService.class.getName());
250         server.addFilterClass("/*", TestFilter.class.getName());
251         server.waitedStart(5000);
252
253         assertTrue(HttpServletServerFactoryInstance.getServerFactory().get(port).isAlive());
254
255         RestEchoReqResp request = new RestEchoReqResp();
256         request.setRequestId(100);
257         request.setText(SOME_TEXT);
258         String reqText = gson.toJson(request);
259
260         String response = http(portUrl + JUNIT_ECHO_FULL_REQUEST, JSON_MEDIA, reqText);
261         assertEquals(reqText, response);
262
263         assertTrue(MyJacksonProvider.hasReadSome());
264         assertTrue(MyJacksonProvider.hasWrittenSome());
265
266         assertFalse(MyGsonProvider.hasReadSome());
267         assertFalse(MyGsonProvider.hasWrittenSome());
268
269         assertFalse(MyYamlProvider.hasReadSome());
270         assertFalse(MyYamlProvider.hasWrittenSome());
271     }
272
273     @Test
274     public void testGsonClassServer() throws Exception {
275         logger.info("-- testGsonClassServer() --");
276
277         HttpServletServer server = HttpServletServerFactoryInstance.getServerFactory()
278                         .build("echo", LOCALHOST, port, "/", false, true);
279         server.setSerializationProvider(MyGsonProvider.class.getName());
280         server.addServletClass("/*", RestEchoService.class.getName());
281         server.addFilterClass("/*", TestFilter.class.getName());
282         server.waitedStart(5000);
283
284         assertTrue(HttpServletServerFactoryInstance.getServerFactory().get(port).isAlive());
285
286         RestEchoReqResp request = new RestEchoReqResp();
287         request.setRequestId(100);
288         request.setText(SOME_TEXT);
289         String reqText = gson.toJson(request);
290
291         String response = http(portUrl + JUNIT_ECHO_FULL_REQUEST, JSON_MEDIA, reqText);
292         assertEquals(reqText, response);
293
294         assertTrue(MyGsonProvider.hasReadSome());
295         assertTrue(MyGsonProvider.hasWrittenSome());
296
297         assertFalse(MyJacksonProvider.hasReadSome());
298         assertFalse(MyJacksonProvider.hasWrittenSome());
299
300         assertFalse(MyYamlProvider.hasReadSome());
301         assertFalse(MyYamlProvider.hasWrittenSome());
302     }
303
304     @Test
305     public void testYamlClassServer() throws Exception {
306         logger.info("-- testYamlClassServer() --");
307
308         HttpServletServer server = HttpServletServerFactoryInstance.getServerFactory()
309                         .build("echo", LOCALHOST, port, "/", false, true);
310         server.setSerializationProvider(MyYamlProvider.class.getName());
311         server.addServletClass("/*", RestEchoService.class.getName());
312         server.addFilterClass("/*", TestFilter.class.getName());
313         server.waitedStart(5000);
314
315         assertTrue(HttpServletServerFactoryInstance.getServerFactory().get(port).isAlive());
316
317         RestEchoReqResp request = new RestEchoReqResp();
318         request.setRequestId(100);
319         request.setText(SOME_TEXT);
320         String reqText = new StandardYamlCoder().encode(request);
321
322         String response = http(portUrl + JUNIT_ECHO_FULL_REQUEST, YAML_MEDIA, reqText);
323
324         // response reader strips newlines, so we should, too, before comparing
325         assertEquals(reqText.replace("\n", ""), response);
326
327         assertTrue(MyYamlProvider.hasReadSome());
328         assertTrue(MyYamlProvider.hasWrittenSome());
329
330         assertFalse(MyGsonProvider.hasReadSome());
331         assertFalse(MyGsonProvider.hasWrittenSome());
332
333         assertFalse(MyJacksonProvider.hasReadSome());
334         assertFalse(MyJacksonProvider.hasWrittenSome());
335     }
336
337     @Test
338     public void testSerialize() {
339         HttpServletServer server = HttpServletServerFactoryInstance.getServerFactory()
340                         .build("echo", LOCALHOST, port, "/", false, true);
341         server.addServletPackage("/*", this.getClass().getPackage().getName());
342         server.addFilterClass("/*", TestFilter.class.getName());
343
344         // ensure we can serialize the server
345         new GsonTestUtils().compareGson(server, HttpServerTest.class);
346     }
347
348     @Test
349     public void testSingleServer() throws Exception {
350         logger.info("-- testSingleServer() --");
351
352         HttpServletServer server = HttpServletServerFactoryInstance.getServerFactory()
353                         .build("echo", LOCALHOST, port, "/", false, true);
354         server.addServletPackage("/*", this.getClass().getPackage().getName());
355         server.addFilterClass("/*", TestFilter.class.getName());
356         server.waitedStart(5000);
357
358         assertTrue(HttpServletServerFactoryInstance.getServerFactory().get(port).isAlive());
359         assertFalse(HttpServletServerFactoryInstance.getServerFactory().get(port).isAaf());
360
361         String response = http(portUrl + JUNIT_ECHO_HELLO);
362         assertEquals(HELLO, response);
363
364         assertThatThrownBy(() -> http(portUrl + SWAGGER_JSON)).isInstanceOf(IOException.class);
365
366         response = http(portUrl + "/junit/echo/hello?block=true");
367         assertEquals("FILTERED", response);
368
369         assertTrue(HttpServletServerFactoryInstance.getServerFactory().get(port).isAlive());
370         assertEquals(1, HttpServletServerFactoryInstance.getServerFactory().inventory().size());
371
372         server.setAafAuthentication("/*");
373         assertTrue(HttpServletServerFactoryInstance.getServerFactory().get(port).isAaf());
374
375         HttpServletServerFactoryInstance.getServerFactory().destroy(port);
376         assertEquals(0, HttpServletServerFactoryInstance.getServerFactory().inventory().size());
377     }
378
379     @Test
380     public void testMultipleServers() throws Exception {
381         logger.info("-- testMultipleServers() --");
382
383         HttpServletServer server1 = HttpServletServerFactoryInstance.getServerFactory()
384                         .build("echo-1", false,LOCALHOST, port, "/", true, true);
385         server1.addServletPackage("/*", this.getClass().getPackage().getName());
386         server1.waitedStart(5000);
387
388         int port2 = port + 1;
389
390         HttpServletServer server2 = HttpServletServerFactoryInstance.getServerFactory()
391                         .build("echo-2", LOCALHOST, port2, "/", false, true);
392         server2.addServletPackage("/*", this.getClass().getPackage().getName());
393         server2.waitedStart(5000);
394
395         assertTrue(HttpServletServerFactoryInstance.getServerFactory().get(port).isAlive());
396         assertTrue(HttpServletServerFactoryInstance.getServerFactory().get(port2).isAlive());
397
398         String response = http(portUrl + JUNIT_ECHO_HELLO);
399         assertTrue(HELLO.equals(response));
400
401         response = http(portUrl + SWAGGER_JSON);
402         assertTrue(response != null);
403
404         response = http(LOCALHOST_PREFIX + port2 + JUNIT_ECHO_HELLO);
405         assertTrue(HELLO.equals(response));
406
407         assertThatThrownBy(() -> http(LOCALHOST_PREFIX + port2 + SWAGGER_JSON)).isInstanceOf(IOException.class);
408
409         HttpServletServerFactoryInstance.getServerFactory().destroy();
410         assertTrue(HttpServletServerFactoryInstance.getServerFactory().inventory().isEmpty());
411     }
412
413     @Test
414     public void testMultiServicePackage() throws Exception {
415         logger.info("-- testMultiServicePackage() --");
416
417         String randomName = UUID.randomUUID().toString();
418
419         HttpServletServer server = HttpServletServerFactoryInstance.getServerFactory()
420                         .build(randomName, LOCALHOST, port, "/", false, true);
421         server.addServletPackage("/*", this.getClass().getPackage().getName());
422         server.waitedStart(5000);
423
424         assertTrue(HttpServletServerFactoryInstance.getServerFactory().get(port).isAlive());
425
426         String response = http(portUrl + JUNIT_ECHO_HELLO);
427         assertTrue(HELLO.equals(response));
428
429         response = http(portUrl + "/junit/endpoints/http/servers");
430         assertTrue(response.contains(randomName));
431
432         HttpServletServerFactoryInstance.getServerFactory().destroy();
433         assertTrue(HttpServletServerFactoryInstance.getServerFactory().inventory().isEmpty());
434     }
435
436     @Test
437     public void testServiceClass() throws Exception {
438         logger.info("-- testServiceClass() --");
439         String randomName = UUID.randomUUID().toString();
440
441         HttpServletServer server = HttpServletServerFactoryInstance.getServerFactory()
442                         .build(randomName, LOCALHOST, port, "/", false, true);
443         server.addServletClass("/*", RestEchoService.class.getName());
444         server.waitedStart(5000);
445
446         assertTrue(HttpServletServerFactoryInstance.getServerFactory().get(port).isAlive());
447
448         String response = http(portUrl + JUNIT_ECHO_HELLO);
449         assertTrue(HELLO.equals(response));
450
451         HttpServletServerFactoryInstance.getServerFactory().destroy();
452         assertTrue(HttpServletServerFactoryInstance.getServerFactory().inventory().isEmpty());
453     }
454
455     @Test
456     public void testMultiServiceClass() throws Exception {
457         logger.info("-- testMultiServiceClass() --");
458
459         String randomName = UUID.randomUUID().toString();
460
461         HttpServletServer server = HttpServletServerFactoryInstance.getServerFactory()
462                         .build(randomName, LOCALHOST, port, "/", false, true);
463         server.addServletClass("/*", RestEchoService.class.getName());
464         server.addServletClass("/*", RestEndpoints.class.getName());
465         server.waitedStart(5000);
466
467         assertTrue(HttpServletServerFactoryInstance.getServerFactory().get(port).isAlive());
468
469         String response = http(portUrl + JUNIT_ECHO_HELLO);
470         assertTrue(HELLO.equals(response));
471
472         response = http(portUrl + "/junit/endpoints/http/servers");
473         assertTrue(response.contains(randomName));
474
475         HttpServletServerFactoryInstance.getServerFactory().destroy();
476         assertTrue(HttpServletServerFactoryInstance.getServerFactory().inventory().isEmpty());
477     }
478
479     /**
480      * performs an http request.
481      *
482      * @throws MalformedURLException make sure URL is good
483      * @throws IOException thrown is IO exception occurs
484      * @throws InterruptedException thrown if thread interrupted occurs
485      */
486     private String http(String urlString)
487             throws IOException, InterruptedException {
488         URL url = new URL(urlString);
489         if (!NetworkUtil.isTcpPortOpen(url.getHost(), url.getPort(), 25, 100)) {
490             throw new IllegalStateException("port never opened: " + url);
491         }
492         return response(url.openConnection());
493     }
494
495     /**
496      * Performs an http request.
497      *
498      * @throws MalformedURLException make sure URL is good
499      * @throws IOException thrown is IO exception occurs
500      * @throws InterruptedException thrown if thread interrupted occurs
501      */
502     private String http(String urlString, String mediaType, String post)
503             throws IOException, InterruptedException {
504         URL url = new URL(urlString);
505         if (!NetworkUtil.isTcpPortOpen(url.getHost(), url.getPort(), 25, 100)) {
506             throw new IllegalStateException("port never opened: " + url);
507         }
508         HttpURLConnection conn = (HttpURLConnection) url.openConnection();
509         conn.setRequestMethod("POST");
510         conn.setDoOutput(true);
511         conn.setRequestProperty("Content-Type", mediaType);
512         conn.setRequestProperty("Accept", mediaType);
513         IOUtils.write(post, conn.getOutputStream());
514         return response(conn);
515     }
516
517     /**
518      * gets http response.
519      *
520      * @param conn connection from which to read
521      *
522      * @throws IOException if an I/O error occurs
523      */
524     private String response(URLConnection conn) throws IOException {
525         try (InputStream inpstr = conn.getInputStream()) {
526             return String.join("", IOUtils.readLines(inpstr));
527         }
528     }
529
530 }