5239b8003a599fd9f96e38567a82a5a993169bc0
[dmaap/datarouter.git] / datarouter-prov / src / test / java / org / onap / dmaap / datarouter / provisioning / InternalServletTest.java
1 /*******************************************************************************
2  * ============LICENSE_START==================================================
3  * * org.onap.dmaap
4  * * ===========================================================================
5  * * Copyright © 2017 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  * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
21  * *
22  ******************************************************************************/
23 package org.onap.dmaap.datarouter.provisioning;
24
25 import static org.hamcrest.Matchers.notNullValue;
26 import static org.mockito.Matchers.anyString;
27 import static org.mockito.Matchers.argThat;
28 import static org.mockito.Matchers.eq;
29 import static org.mockito.Mockito.mock;
30 import static org.mockito.Mockito.verify;
31 import static org.mockito.Mockito.when;
32 import static org.onap.dmaap.datarouter.provisioning.BaseServlet.BEHALF_HEADER;
33
34 import java.io.File;
35 import java.net.InetAddress;
36 import javax.persistence.EntityManager;
37 import javax.persistence.EntityManagerFactory;
38 import javax.persistence.Persistence;
39 import javax.servlet.ServletInputStream;
40 import javax.servlet.ServletOutputStream;
41 import javax.servlet.http.HttpServletRequest;
42 import javax.servlet.http.HttpServletResponse;
43
44 import ch.qos.logback.classic.spi.ILoggingEvent;
45 import ch.qos.logback.core.read.ListAppender;
46 import org.apache.commons.lang3.reflect.FieldUtils;
47 import org.junit.Assert;
48 import org.junit.Before;
49 import org.junit.Test;
50 import org.junit.runner.RunWith;
51 import org.junit.BeforeClass;
52 import org.junit.AfterClass;
53 import org.mockito.Mock;
54
55 import org.onap.dmaap.datarouter.provisioning.beans.Deleteable;
56 import org.onap.dmaap.datarouter.provisioning.beans.Insertable;
57 import org.onap.dmaap.datarouter.provisioning.beans.LogRecord;
58 import org.onap.dmaap.datarouter.provisioning.beans.Parameters;
59 import org.onap.dmaap.datarouter.provisioning.beans.Updateable;
60 import org.powermock.api.mockito.PowerMockito;
61 import org.powermock.core.classloader.annotations.PrepareForTest;
62 import org.powermock.modules.junit4.PowerMockRunner;
63
64 @RunWith(PowerMockRunner.class)
65 @PrepareForTest(LogRecord.class)
66 public class InternalServletTest extends DrServletTestBase {
67   private static EntityManagerFactory emf;
68   private static EntityManager em;
69   private InternalServlet internalServlet;
70
71   @Mock
72   private HttpServletRequest request;
73
74   @Mock
75   private HttpServletResponse response;
76
77   ListAppender<ILoggingEvent> listAppender;
78
79   @BeforeClass
80   public static void init() {
81     emf = Persistence.createEntityManagerFactory("dr-unit-tests");
82     em = emf.createEntityManager();
83     System.setProperty(
84             "org.onap.dmaap.datarouter.provserver.properties",
85             "src/test/resources/h2Database.properties");
86   }
87
88   @AfterClass
89   public static void tearDownClass() {
90     em.clear();
91     em.close();
92     emf.close();
93   }
94
95   @Before
96   public void setUp() throws Exception {
97       listAppender = setTestLogger(InternalServlet.class);
98       internalServlet = new InternalServlet();
99       setUpValidAuthorisedRequest();
100   }
101
102   @Test
103   public void Given_Request_Is_HTTP_GET_And_Address_Not_Authorized_When_HTTPS_Is_Required_Then_Forbidden_Response_Is_Generated()
104       throws Exception {
105     when(request.getRemoteAddr()).thenReturn("127.100.0.3");
106     internalServlet.doGet(request, response);
107     verify(response)
108         .sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
109     verifyEnteringExitCalled(listAppender);
110   }
111
112   @Test
113   public void Given_Request_Is_HTTP_GET_With_Halt_In_Endpoint_But_Not_Sent_From_Localhost_Then_Forbidden_Response_Is_Generated()
114       throws Exception {
115     when(request.getPathInfo()).thenReturn("/halt");
116     when(request.isSecure()).thenReturn(false);
117     when(request.getRemoteAddr()).thenReturn("127.100.0.3");
118     internalServlet.doGet(request, response);
119     verify(response).setStatus(eq(HttpServletResponse.SC_FORBIDDEN));
120   }
121
122   @Test
123   public void Given_Request_Is_HTTP_GET_With_Halt_In_Endpoint_Then_Request_Succeeds() throws Exception {
124     when(request.getPathInfo()).thenReturn("/halt");
125     when(request.isSecure()).thenReturn(false);
126     when(request.getRemoteAddr()).thenReturn("127.0.0.1");
127     internalServlet.doGet(request, response);
128     verify(response).setStatus(eq(HttpServletResponse.SC_OK));
129   }
130
131   @Test
132   public void Given_Request_Is_HTTP_GET_With_FetchProv_In_Endpoint_Then_Request_Succeeds()
133       throws Exception {
134     when(request.getPathInfo()).thenReturn("/fetchProv");
135     when(request.isSecure()).thenReturn(false);
136     internalServlet.doGet(request, response);
137     verify(response).setStatus(eq(HttpServletResponse.SC_OK));
138       verifyEnteringExitCalled(listAppender);
139   }
140
141   @Test
142   public void Given_Request_Is_HTTP_GET_With_Prov_In_Endpoint_Then_Request_Succeeds() throws Exception {
143     when(request.getPathInfo()).thenReturn("/prov");
144     when(request.getQueryString()).thenReturn(null);
145     setPokerToNotCreateTimers();
146     ServletOutputStream outStream = mock(ServletOutputStream.class);
147     when(response.getOutputStream()).thenReturn(outStream);
148     internalServlet.doGet(request, response);
149     verify(response).setStatus(eq(HttpServletResponse.SC_OK));
150   }
151
152   @Test
153   public void Given_Request_Is_HTTP_GET_With_Logs_In_Endpoint_Then_Request_Succeeds() throws Exception {
154     when(request.getPathInfo()).thenReturn("/logs/");
155     ServletOutputStream outStream = mock(ServletOutputStream.class);
156     when(response.getOutputStream()).thenReturn(outStream);
157     internalServlet.doGet(request, response);
158     verify(response).setStatus(eq(HttpServletResponse.SC_OK));
159   }
160
161   @Test
162   public void Given_Request_Is_HTTP_GET_Starts_With_Logs_In_Endpoint_Then_Request_Succeeds()
163       throws Exception {
164     when(request.getPathInfo()).thenReturn("/logs/TestFile");
165     internalServlet.doGet(request, response);
166     verify(response)
167         .sendError(eq(HttpServletResponse.SC_NO_CONTENT), argThat(notNullValue(String.class)));
168   }
169
170   @Test
171   public void Given_Request_Is_HTTP_GET_Starts_With_Logs_In_Endpoint_And_File_Exists_Then_Request_Returns_Ok()
172       throws Exception {
173     when(request.getPathInfo()).thenReturn("/logs/testFile.txt");
174     File testDir = new File("unit-test-logs");
175     File testFile = new File("unit-test-logs/testFile.txt");
176     testDir.mkdirs();
177     testFile.createNewFile();
178     testFile.deleteOnExit();
179     ServletOutputStream outStream = mock(ServletOutputStream.class);
180     when(response.getOutputStream()).thenReturn(outStream);
181     internalServlet.doGet(request, response);
182     verify(response).setStatus(eq(HttpServletResponse.SC_OK));
183   }
184
185   @Test
186   public void Given_Request_Is_HTTP_GET_With_Api_In_Endpoint_Then_Request_Succeeds() throws Exception {
187     when(request.getPathInfo()).thenReturn("/api/DELIVERY_MAX_RETRY_INTERVAL");
188     ServletOutputStream outStream = mock(ServletOutputStream.class);
189     when(response.getOutputStream()).thenReturn(outStream);
190     internalServlet.doGet(request, response);
191     verify(response).setStatus(eq(HttpServletResponse.SC_OK));
192   }
193
194   @Test
195   public void Given_Request_Is_HTTP_GET_With_Drlogs_In_Endpoint_Then_Request_Succeeds()
196       throws Exception {
197     when(request.getPathInfo()).thenReturn("/drlogs/");
198     ServletOutputStream outStream = mock(ServletOutputStream.class);
199     when(response.getOutputStream()).thenReturn(outStream);
200     internalServlet.doGet(request, response);
201     verify(response).setStatus(eq(HttpServletResponse.SC_OK));
202   }
203
204   @Test
205   public void Given_Request_Is_HTTP_GET_With_Incorrect_Endpoint_Then_No_Content_Response_Is_Generated()
206       throws Exception {
207     when(request.getPathInfo()).thenReturn("/incorrect/");
208     internalServlet.doGet(request, response);
209     verify(response)
210         .sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
211   }
212
213   @Test
214   public void Given_Request_Is_HTTP_PUT_And_Address_Not_Authorized_When_HTTPS_Is_Required_Then_Forbidden_Response_Is_Generated()
215       throws Exception {
216     when(request.getRemoteAddr()).thenReturn("127.100.0.3");
217     FieldUtils.writeDeclaredStaticField(BaseServlet.class, "isAddressAuthEnabled", "true", true);
218     internalServlet.doPut(request, response);
219     verify(response)
220         .sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
221     verifyEnteringExitCalled(listAppender);
222   }
223
224   @Test
225   public void Given_Request_Is_HTTP_PUT_With_Api_In_Endpoint_Request_Succeeds() throws Exception {
226     when(request.getPathInfo()).thenReturn("/api/NODES");
227     String[] values = {"V", "a", "l", "u", "e", "s"};
228     when(request.getParameterValues(anyString())).thenReturn(values);
229     internalServlet = internalServerSuccess();
230     setPokerToNotCreateTimers();
231     internalServlet.doPut(request, response);
232     verify(response).setStatus(eq(HttpServletResponse.SC_OK));
233     verifyEnteringExitCalled(listAppender);
234   }
235
236   @Test
237   public void Given_Request_Is_HTTP_PUT_With_Api_In_Endpoint_And_Update_Fails_Then_Internal_Server_Error_Is_Generated()
238       throws Exception {
239     when(request.getPathInfo()).thenReturn("/api/NODES");
240     String[] values = {"V", "a", "l", "u", "e", "s"};
241     when(request.getParameterValues(anyString())).thenReturn(values);
242     internalServlet = internalServerFailure();
243     internalServlet.doPut(request, response);
244     verify(response).sendError(eq(HttpServletResponse.SC_INTERNAL_SERVER_ERROR),
245         argThat(notNullValue(String.class)));
246   }
247
248   @Test
249   public void Given_Request_Is_HTTP_PUT_With_Incorrect_Endpoint_Then_Not_Found_Error_Is_Generated()
250       throws Exception {
251     when(request.getPathInfo()).thenReturn("/incorrect");
252     internalServlet.doPut(request, response);
253     verify(response)
254         .sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
255   }
256
257   @Test
258   public void Given_Request_Is_HTTP_DELETE_And_Address_Not_Authorized_When_HTTPS_Is_Required_Then_Forbidden_Response_Is_Generated()
259       throws Exception {
260     when(request.getRemoteAddr()).thenReturn("127.100.0.3");
261     FieldUtils.writeDeclaredStaticField(BaseServlet.class, "isAddressAuthEnabled", "true", true);
262     internalServlet.doDelete(request, response);
263     verify(response)
264         .sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
265     verifyEnteringExitCalled(listAppender);
266   }
267
268   @Test
269   public void Given_Request_Is_HTTP_DELETE_With_Api_In_Endpoint_Request_Succeeds()
270       throws Exception {
271     when(request.getPathInfo()).thenReturn("/api/NODES");
272     String[] values = {"V", "a", "l", "u", "e", "s"};
273     when(request.getParameterValues(anyString())).thenReturn(values);
274     internalServlet = internalServerSuccess();
275     setPokerToNotCreateTimers();
276     internalServlet.doDelete(request, response);
277     verify(response).setStatus(eq(HttpServletResponse.SC_OK));
278     verifyEnteringExitCalled(listAppender);
279   }
280
281   @Test
282   public void Given_Request_Is_HTTP_DELETE_With_LogRollInterval_Api_In_Endpoint_Request_Succeeds() {
283     when(request.getPathInfo()).thenReturn("/api/LOGROLL_INTERVAL");
284     internalServlet.doDelete(request, response);
285     verify(response).setStatus(eq(HttpServletResponse.SC_OK));
286     Parameters p1 = Parameters.getParameter("NODES");
287     Assert.assertEquals("{\"keyname\":\"NODES\",\"value\":\"dmaap-dr-node\"}", p1.asJSONObject().toString());
288     Assert.assertEquals("PARAM: keyname=NODES, value=dmaap-dr-node", p1.toString());
289   }
290
291   @Test
292   public void Given_Request_Is_HTTP_DELETE_With_Api_In_Endpoint_And_Delete_Fails_Then_Internal_Server_Error_Is_Generated()
293       throws Exception {
294     when(request.getPathInfo()).thenReturn("/api/NODES");
295     String[] values = {"V", "a", "l", "u", "e", "s"};
296     when(request.getParameterValues(anyString())).thenReturn(values);
297     internalServlet = internalServerFailure();
298     internalServlet.doDelete(request, response);
299     verify(response).sendError(eq(HttpServletResponse.SC_INTERNAL_SERVER_ERROR),
300         argThat(notNullValue(String.class)));
301   }
302
303   @Test
304   public void Given_Request_Is_HTTP_DELETE_With_Incorrect_Endpoint_Then_Not_Found_Error_Is_Generated()
305       throws Exception {
306     when(request.getPathInfo()).thenReturn("/incorrect");
307     internalServlet.doDelete(request, response);
308     verify(response)
309         .sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
310   }
311
312   @Test
313   public void Given_Request_Is_HTTP_POST_And_Address_Not_Authorized_When_HTTPS_Is_Required_Then_Forbidden_Response_Is_Generated()
314       throws Exception {
315     when(request.getRemoteAddr()).thenReturn("127.100.0.3");
316     internalServlet.doPost(request, response);
317     verify(response)
318         .sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
319     verifyEnteringExitCalled(listAppender);
320   }
321
322   @Test
323   public void Given_Request_Is_HTTP_POST_With_Api_In_Endpoint_Request_Succeeds() throws Exception {
324     when(request.getPathInfo()).thenReturn("/api/key");
325     String[] values = {"V", "a", "l", "u", "e", "s"};
326     when(request.getParameterValues(anyString())).thenReturn(values);
327     internalServlet = internalServerSuccess();
328     setPokerToNotCreateTimers();
329     internalServlet.doPost(request, response);
330     verify(response).setStatus(eq(HttpServletResponse.SC_OK));
331     verifyEnteringExitCalled(listAppender);
332   }
333
334   @Test
335   public void Given_Request_Is_HTTP_POST_With_Api_In_Endpoint_And_Insert_Fails_Then_Internal_Server_Error_Is_Generated()
336       throws Exception {
337     when(request.getPathInfo()).thenReturn("/api/Key");
338     String[] values = {"V", "a", "l", "u", "e", "s"};
339     when(request.getParameterValues(anyString())).thenReturn(values);
340     internalServlet = internalServerFailure();
341     internalServlet.doPost(request, response);
342     verify(response).sendError(eq(HttpServletResponse.SC_INTERNAL_SERVER_ERROR),
343         argThat(notNullValue(String.class)));
344   }
345
346   @Test
347   public void Given_Request_Is_HTTP_POST_To_Logs_And_Content_Header_Is_Not_Supported_Type_Then_Unsupported_Media_Type_Response_Is_Generated() {
348     when(request.getHeader("Content-Type")).thenReturn("stub_contentType");
349     when(request.getPathInfo()).thenReturn("/logs/");
350     internalServlet.doPost(request, response);
351     verify(response).setStatus(eq(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE));
352   }
353
354   @Test
355   public void Given_Request_Is_HTTP_POST_To_Logs_And_Content_Encoding_Is_Not_Supported_Type_Then_Unsupported_Media_Type_Response_Is_Generated() {
356     when(request.getHeader("Content-Encoding")).thenReturn("not-supported");
357     when(request.getPathInfo()).thenReturn("/logs/");
358     internalServlet.doPost(request, response);
359     verify(response).setStatus(eq(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE));
360   }
361
362   @Test
363   public void Given_Request_Is_HTTP_POST_To_Logs_Then_Request_Succeeds()
364       throws Exception {
365     when(request.getHeader("Content-Encoding")).thenReturn("gzip");
366     when(request.getPathInfo()).thenReturn("/logs/");
367     ServletInputStream inStream = mock(ServletInputStream.class);
368     when(request.getInputStream()).thenReturn(inStream);
369     File testDir = new File("unit-test-logs/spool");
370     testDir.mkdirs();
371     testDir.deleteOnExit();
372     internalServlet.doPost(request, response);
373     verify(response).setStatus(eq(HttpServletResponse.SC_CREATED));
374   }
375
376   @Test
377   public void Given_Request_Is_HTTP_POST_To_Drlogs_And_Then_Unsupported_Media_Type_Response_Is_Generated() {
378     when(request.getHeader("Content-Type")).thenReturn("stub_contentType");
379     when(request.getPathInfo()).thenReturn("/drlogs/");
380     internalServlet.doPost(request, response);
381     verify(response).setStatus(eq(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE));
382   }
383
384   @Test
385   public void Given_Request_Is_HTTP_POST_To_Drlogs_And_Request_Succeeds() throws Exception {
386     when(request.getPathInfo()).thenReturn("/drlogs/");
387     ServletInputStream inStream = mock(ServletInputStream.class);
388     when(inStream.read()).thenReturn(1, -1);
389     when(request.getInputStream()).thenReturn(inStream);
390     PowerMockito.mockStatic(LogRecord.class);
391     internalServlet.doPost(request, response);
392     verify(response).setStatus(eq(HttpServletResponse.SC_OK));
393   }
394
395   @Test
396   public void Given_Request_Is_HTTP_POST_To_Api_And_Request_Succeeds() {
397     when(request.getPathInfo()).thenReturn("/api/NEW_PARAM?val=blah");
398     internalServlet.doPost(request, response);
399     verify(response).setStatus(eq(HttpServletResponse.SC_OK));
400   }
401
402   @Test
403   public void Given_Request_Is_HTTP_POST_With_Incorrect_Endpoint_Then_Not_Found_Error_Is_Generated()
404       throws Exception {
405     when(request.getPathInfo()).thenReturn("/incorrect/");
406     internalServlet.doPost(request, response);
407     verify(response)
408         .sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
409   }
410
411   private void setUpValidAuthorisedRequest() throws Exception {
412     setUpValidSecurityOnHttpRequest();
413     setBehalfHeader("Stub_Value");
414     setValidPathInfoInHttpHeader();
415     when(request.getHeader("Content-Type")).thenReturn("text/plain");
416     when(request.getHeader("Content-Encoding")).thenReturn("gzip");
417   }
418
419   private void setUpValidSecurityOnHttpRequest() throws Exception {
420     when(request.isSecure()).thenReturn(true);
421     when(request.getRemoteAddr()).thenReturn(InetAddress.getLocalHost().getHostAddress());
422     InetAddress[] nodeAddresses = new InetAddress[1];
423     nodeAddresses[0] = InetAddress.getLocalHost();
424     FieldUtils.writeDeclaredStaticField(BaseServlet.class, "nodeAddresses", nodeAddresses, true);
425     FieldUtils.writeDeclaredStaticField(BaseServlet.class, "requireCert", false, true);
426   }
427
428   private void setBehalfHeader(String headerValue) {
429     when(request.getHeader(BEHALF_HEADER)).thenReturn(headerValue);
430   }
431
432   private void setValidPathInfoInHttpHeader() {
433     when(request.getPathInfo()).thenReturn("/123");
434   }
435
436   private void setPokerToNotCreateTimers() throws Exception {
437     Poker poker = mock(Poker.class);
438     FieldUtils.writeDeclaredStaticField(Poker.class, "poker", poker, true);
439   }
440
441   private InternalServlet internalServerSuccess() {
442     InternalServlet internalServlet = new InternalServlet() {
443
444       protected boolean doUpdate(Updateable bean) {
445         return true;
446       }
447
448       protected boolean doDelete(Deleteable bean) {
449         return true;
450       }
451
452       protected boolean doInsert(Insertable bean) {
453         return true;
454       }
455     };
456     return internalServlet;
457   }
458
459   private InternalServlet internalServerFailure() {
460     InternalServlet internalServlet = new InternalServlet() {
461
462       protected boolean doUpdate(Updateable bean) {
463         return false;
464       }
465
466       protected boolean doDelete(Deleteable bean) {
467         return false;
468       }
469
470       protected boolean doInsert(Insertable bean) {
471         return false;
472       }
473     };
474     return internalServlet;
475   }
476 }