Replace ATT headers
[dmaap/datarouter.git] / datarouter-prov / src / test / java / org / onap / dmaap / datarouter / provisioning / FeedServletTest.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 ch.qos.logback.classic.spi.ILoggingEvent;
26 import ch.qos.logback.core.read.ListAppender;
27 import org.apache.commons.lang3.reflect.FieldUtils;
28 import org.jetbrains.annotations.NotNull;
29 import org.json.JSONArray;
30 import org.json.JSONObject;
31 import org.junit.AfterClass;
32 import org.junit.Before;
33 import org.junit.BeforeClass;
34 import org.junit.Test;
35 import org.junit.runner.RunWith;
36 import org.mockito.Mock;
37 import org.onap.dmaap.datarouter.authz.AuthorizationResponse;
38 import org.onap.dmaap.datarouter.authz.Authorizer;
39 import org.onap.dmaap.datarouter.provisioning.beans.Feed;
40 import org.onap.dmaap.datarouter.provisioning.beans.Updateable;
41 import org.onap.dmaap.datarouter.provisioning.utils.DB;
42 import org.powermock.modules.junit4.PowerMockRunner;
43
44 import javax.persistence.EntityManager;
45 import javax.persistence.EntityManagerFactory;
46 import javax.persistence.Persistence;
47 import javax.servlet.ServletInputStream;
48 import javax.servlet.ServletOutputStream;
49 import javax.servlet.http.HttpServletRequest;
50 import javax.servlet.http.HttpServletResponse;
51 import java.sql.SQLException;
52 import java.util.HashSet;
53 import java.util.Set;
54
55 import static org.hamcrest.Matchers.notNullValue;
56 import static org.mockito.Mockito.*;
57 import static org.onap.dmaap.datarouter.provisioning.BaseServlet.BEHALF_HEADER;
58
59
60 @RunWith(PowerMockRunner.class)
61 public class FeedServletTest extends DrServletTestBase {
62
63     private static FeedServlet feedServlet;
64
65     @Mock
66     private HttpServletRequest request;
67     @Mock
68     private HttpServletResponse response;
69
70     private static EntityManagerFactory emf;
71     private static EntityManager em;
72     private DB db;
73
74     ListAppender<ILoggingEvent> listAppender;
75
76     @BeforeClass
77     public static void init() {
78         emf = Persistence.createEntityManagerFactory("dr-unit-tests");
79         em = emf.createEntityManager();
80         System.setProperty(
81                 "org.onap.dmaap.datarouter.provserver.properties",
82                 "src/test/resources/h2Database.properties");
83     }
84
85     @AfterClass
86     public static void tearDownClass() {
87         em.clear();
88         em.close();
89         emf.close();
90     }
91
92     @Before
93     public void setUp() throws Exception {
94         listAppender = setTestLogger(FeedServlet.class);
95         feedServlet = new FeedServlet();
96         db = new DB();
97         setAuthoriserToReturnRequestIsAuthorized();
98         setUpValidAuthorisedRequest();
99         setUpValidSecurityOnHttpRequest();
100         setUpValidContentHeadersAndJSONOnHttpRequest();
101     }
102
103     @Test
104     public void Given_Request_Is_HTTP_DELETE_And_Is_Not_Secure_When_HTTPS_Is_Required_Then_Forbidden_Response_Is_Generated()
105         throws Exception {
106         when(request.isSecure()).thenReturn(false);
107         feedServlet.doDelete(request, response);
108         verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
109         verifyEnteringExitCalled(listAppender);
110     }
111
112
113     @Test
114     public void Given_Request_Is_HTTP_DELETE_And_BEHALF_HEADER_Is_Not_Set_In_Request_Then_Bad_Request_Response_Is_Generated()
115         throws Exception {
116         setBehalfHeader(null);
117         feedServlet.doDelete(request, response);
118         verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
119     }
120
121
122     @Test
123     public void Given_Request_Is_HTTP_DELETE_And_Path_Header_Is_Not_Set_In_Request_With_Valid_Path_Then_Bad_Request_Response_Is_Generated()
124         throws Exception {
125         when(request.getPathInfo()).thenReturn(null);
126         feedServlet.doDelete(request, response);
127         verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
128     }
129
130
131     @Test
132     public void Given_Request_Is_HTTP_DELETE_And_Feed_Id_Is_Invalid_Then_Not_Found_Response_Is_Generated()
133         throws Exception {
134         when(request.getPathInfo()).thenReturn("/123");
135         feedServlet.doDelete(request, response);
136         verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
137     }
138
139
140     @Test
141     public void Given_Request_Is_HTTP_DELETE_And_Request_Is_Not_Authorized_Then_Forbidden_Response_Is_Generated()
142         throws Exception {
143         setAuthoriserToReturnRequestNotAuthorized();
144         feedServlet.doDelete(request, response);
145         verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
146     }
147
148
149     @Test
150     public void Given_Request_Is_HTTP_DELETE_And_Delete_On_Database_Fails_An_Internal_Server_Error_Is_Reported()
151         throws Exception {
152         FeedServlet feedServlet = new FeedServlet() {
153             protected boolean doUpdate(Updateable bean) {
154                 return false;
155             }
156         };
157         feedServlet.doDelete(request, response);
158         verify(response)
159             .sendError(eq(HttpServletResponse.SC_INTERNAL_SERVER_ERROR), argThat(notNullValue(String.class)));
160     }
161
162
163     @Test
164     public void Given_Request_Is_HTTP_DELETE_And_Delete_On_Database_Succeeds_A_NO_CONTENT_Response_Is_Generated()
165         throws Exception {
166         feedServlet.doDelete(request, response);
167         verify(response).setStatus(eq(HttpServletResponse.SC_NO_CONTENT));
168         reinsertFeedIntoDb();
169         verifyEnteringExitCalled(listAppender);
170     }
171
172     @Test
173     public void Given_Request_Is_HTTP_GET_And_Is_Not_Secure_When_HTTPS_Is_Required_Then_Forbidden_Response_Is_Generated()
174         throws Exception {
175         when(request.isSecure()).thenReturn(false);
176         feedServlet.doGet(request, response);
177         verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
178         verifyEnteringExitCalled(listAppender);
179     }
180
181     @Test
182     public void Given_Request_Is_HTTP_GET_And_BEHALF_HEADER_Is_Not_Set_In_Request_Then_Bad_Request_Response_Is_Generated()
183         throws Exception {
184         setBehalfHeader(null);
185         feedServlet.doGet(request, response);
186         verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
187     }
188
189
190     @Test
191     public void Given_Request_Is_HTTP_GET_And_Path_Header_Is_Not_Set_In_Request_With_Valid_Path_Then_Bad_Request_Response_Is_Generated()
192         throws Exception {
193         when(request.getPathInfo()).thenReturn(null);
194         feedServlet.doGet(request, response);
195         verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
196     }
197
198
199     @Test
200     public void Given_Request_Is_HTTP_GET_And_Feed_Id_Is_Invalid_Then_Not_Found_Response_Is_Generated()
201         throws Exception {
202         when(request.getPathInfo()).thenReturn("/123");
203         feedServlet.doGet(request, response);
204         verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
205     }
206
207
208     @Test
209     public void Given_Request_Is_HTTP_GET_And_Request_Is_Not_Authorized_Then_Forbidden_Response_Is_Generated()
210         throws Exception {
211         setAuthoriserToReturnRequestNotAuthorized();
212         feedServlet.doGet(request, response);
213         verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
214     }
215
216
217     @Test
218     public void Given_Request_Is_HTTP_GET_And_Request_Succeeds() throws Exception {
219         ServletOutputStream outStream = mock(ServletOutputStream.class);
220         when(response.getOutputStream()).thenReturn(outStream);
221         feedServlet.doGet(request, response);
222         verify(response).setStatus(eq(HttpServletResponse.SC_OK));
223         verifyEnteringExitCalled(listAppender);
224     }
225
226
227     @Test
228     public void Given_Request_Is_HTTP_PUT_And_Is_Not_Secure_When_HTTPS_Is_Required_Then_Forbidden_Response_Is_Generated()
229         throws Exception {
230         when(request.isSecure()).thenReturn(false);
231         feedServlet.doPut(request, response);
232         verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
233         verifyEnteringExitCalled(listAppender);
234     }
235
236     @Test
237     public void Given_Request_Is_HTTP_PUT_And_BEHALF_HEADER_Is_Not_Set_In_Request_Then_Bad_Request_Response_Is_Generated()
238         throws Exception {
239         setBehalfHeader(null);
240         feedServlet.doPut(request, response);
241         verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
242     }
243
244
245     @Test
246     public void Given_Request_Is_HTTP_PUT_And_Path_Header_Is_Not_Set_In_Request_With_Valid_Path_Then_Bad_Request_Response_Is_Generated()
247         throws Exception {
248         when(request.getPathInfo()).thenReturn(null);
249         feedServlet.doPut(request, response);
250         verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
251     }
252
253
254     @Test
255     public void Given_Request_Is_HTTP_PUT_And_Feed_Id_Is_Invalid_Then_Not_Found_Response_Is_Generated()
256         throws Exception {
257         when(request.getPathInfo()).thenReturn("/123");
258         feedServlet.doPut(request, response);
259         verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
260     }
261
262     @Test
263     public void Given_Request_Is_HTTP_PUT_And_Content_Header_Is_Not_Supported_Type_Then_Unsupported_Media_Type_Response_Is_Generated()
264         throws Exception {
265         when(request.getHeader("Content-Type")).thenReturn("application/vnd.dmaap-dr.feed-fail; version=2.0");
266         when(request.getContentType()).thenReturn("stub_contentType");
267         feedServlet.doPut(request, response);
268         verify(response)
269             .sendError(eq(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE), argThat(notNullValue(String.class)));
270     }
271
272     @Test
273     public void Given_Request_Is_HTTP_PUT_And_Request_Contains_Badly_Formed_JSON_Then_Bad_Request_Response_Is_Generated()
274         throws Exception {
275         ServletInputStream inStream = mock(ServletInputStream.class);
276         when(request.getInputStream()).thenReturn(inStream);
277         feedServlet.doPut(request, response);
278         verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
279     }
280
281     @Test
282     public void Given_Request_Is_HTTP_PUT_And_Request_Contains_Invalid_JSON_Then_Bad_Request_Response_Is_Generated() throws Exception {
283         FeedServlet feedServlet = new FeedServlet() {
284             protected JSONObject getJSONfromInput(HttpServletRequest req) {
285                 return new JSONObject();
286             }
287         };
288         feedServlet.doPut(request, response);
289         verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
290     }
291
292     @Test
293     public void Given_Request_Is_HTTP_PUT_And_Feed_Change_Is_Not_Publisher_Who_Requested_Feed_Bad_Request_Response_Is_Generated() throws Exception {
294         when(request.getHeader("X-DMAAP-DR-ON-BEHALF-OF-GROUP")).thenReturn(null);
295         JSONObject JSObject = buildRequestJsonObject();
296         FeedServlet feedServlet = new FeedServlet() {
297             protected JSONObject getJSONfromInput(HttpServletRequest req) {
298                 JSONObject jo = new JSONObject();
299                 jo.put("name", "stub_name");
300                 jo.put("version", "1.0");
301                 jo.put("authorization", JSObject);
302                 return jo;
303             }
304         };
305
306         feedServlet.doPut(request, response);
307         verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
308     }
309
310     @Test
311     public void Given_Request_Is_HTTP_PUT_And_Feed_Name_Change_is_Requested_Bad_Request_Response_Is_Generated() throws Exception {
312         JSONObject JSObject = buildRequestJsonObject();
313         FeedServlet feedServlet = new FeedServlet() {
314             protected JSONObject getJSONfromInput(HttpServletRequest req) {
315                 JSONObject jo = new JSONObject();
316                 jo.put("name", "not_stub_name");
317                 jo.put("version", "1.0");
318                 jo.put("authorization", JSObject);
319                 return jo;
320             }
321         };
322         feedServlet.doPut(request, response);
323         verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
324     }
325
326     @Test
327     public void Given_Request_Is_HTTP_PUT_And_Feed_Version_Change_is_Requested_Bad_Request_Response_Is_Generated() throws Exception {
328         JSONObject JSObject = buildRequestJsonObject();
329         FeedServlet feedServlet = new FeedServlet() {
330             protected JSONObject getJSONfromInput(HttpServletRequest req) {
331                 JSONObject jo = new JSONObject();
332                 jo.put("name", "stub_name");
333                 jo.put("version", "2.0");
334                 jo.put("authorization", JSObject);
335                 return jo;
336             }
337         };
338         feedServlet.doPut(request, response);
339         verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
340     }
341
342     @Test
343     public void Given_Request_Is_HTTP_PUT_And_Request_Is_Not_Authorized_Then_Forbidden_Response_Is_Generated() throws Exception {
344         JSONObject JSObject = buildRequestJsonObject();
345         FeedServlet feedServlet = new FeedServlet() {
346             protected JSONObject getJSONfromInput(HttpServletRequest req) {
347                 JSONObject jo = new JSONObject();
348                 jo.put("name", "Feed1");
349                 jo.put("version", "v0.1");
350                 jo.put("authorization", JSObject);
351                 return jo;
352             }
353         };
354         setAuthoriserToReturnRequestNotAuthorized();
355         feedServlet.doPut(request, response);
356         verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
357     }
358
359     @Test
360     public void Given_Request_Is_HTTP_PUT_And_Change_On_Feeds_Fails_An_Internal_Server_Error_Response_Is_Generated() throws Exception {
361         ServletOutputStream outStream = mock(ServletOutputStream.class);
362         when(response.getOutputStream()).thenReturn(outStream);
363
364         JSONObject JSObject = buildRequestJsonObject();
365         FeedServlet feedServlet = new FeedServlet() {
366             protected JSONObject getJSONfromInput(HttpServletRequest req) {
367                 JSONObject jo = new JSONObject();
368                 jo.put("name", "Feed1");
369                 jo.put("version", "v0.1");
370                 jo.put("authorization", JSObject);
371                 return jo;
372             }
373
374             @Override
375             protected boolean doUpdate(Updateable bean) {
376                 return false;
377             }
378         };
379         feedServlet.doPut(request, response);
380         verify(response).sendError(eq(HttpServletResponse.SC_INTERNAL_SERVER_ERROR), argThat(notNullValue(String.class)));
381     }
382
383     @Test
384     public void Given_Request_Is_HTTP_PUT_And_Change_On_Feeds_Suceeds_A_STATUS_OK_Response_Is_Generated() throws Exception {
385         ServletOutputStream outStream = mock(ServletOutputStream.class);
386         when(response.getOutputStream()).thenReturn(outStream);
387         JSONObject JSObject = buildRequestJsonObject();
388         FeedServlet feedServlet = new FeedServlet() {
389             protected JSONObject getJSONfromInput(HttpServletRequest req) {
390                 JSONObject jo = new JSONObject();
391                 jo.put("name", "Feed1");
392                 jo.put("version", "v0.1");
393                 jo.put("authorization", JSObject);
394                 return jo;
395             }
396
397         };
398         feedServlet.doPut(request, response);
399         verify(response).setStatus(eq(HttpServletResponse.SC_OK));
400         verifyEnteringExitCalled(listAppender);
401     }
402
403     @Test
404     public void Given_Request_Is_HTTP_POST_SC_METHOD_NOT_ALLOWED_Response_Is_Generated() throws Exception {
405         feedServlet.doPost(request, response);
406         verify(response).sendError(eq(HttpServletResponse.SC_METHOD_NOT_ALLOWED), argThat(notNullValue(String.class)));
407         verifyEnteringExitCalled(listAppender);
408     }
409
410     @NotNull
411     private JSONObject buildRequestJsonObject() {
412         JSONObject JSObject = new JSONObject();
413         JSONArray endpointIDs = new JSONArray();
414         JSONObject JOEndpointIDs = new JSONObject();
415         JOEndpointIDs.put("id", "stub_endpoint_id");
416         JOEndpointIDs.put("password", "stub_endpoint_password");
417         endpointIDs.put(JOEndpointIDs);
418
419         JSONArray endpointAddresses = new JSONArray();
420         endpointAddresses.put("127.0.0.1");
421
422         JSObject.put("classification", "stub_classification");
423         JSObject.put("endpoint_ids", endpointIDs);
424         JSObject.put("endpoint_addrs", endpointAddresses);
425         return JSObject;
426     }
427
428     private void setUpValidSecurityOnHttpRequest() throws Exception {
429         when(request.isSecure()).thenReturn(true);
430         Set<String> authAddressesAndNetworks = new HashSet<String>();
431         authAddressesAndNetworks.add(("127.0.0.1"));
432         FieldUtils
433             .writeDeclaredStaticField(BaseServlet.class, "authorizedAddressesAndNetworks", authAddressesAndNetworks,
434                 true);
435         FieldUtils.writeDeclaredStaticField(BaseServlet.class, "requireCert", false, true);
436     }
437
438     private void setBehalfHeader(String headerValue) {
439         when(request.getHeader(BEHALF_HEADER)).thenReturn(headerValue);
440     }
441
442     private void setValidPathInfoInHttpHeader() {
443         when(request.getPathInfo()).thenReturn("/1");
444     }
445
446     private void setAuthoriserToReturnRequestNotAuthorized() throws IllegalAccessException {
447         AuthorizationResponse authResponse = mock(AuthorizationResponse.class);
448         Authorizer authorizer = mock(Authorizer.class);
449         FieldUtils.writeDeclaredStaticField(BaseServlet.class, "authz", authorizer, true);
450         when(authorizer.decide(request)).thenReturn(authResponse);
451         when(authResponse.isAuthorized()).thenReturn(false);
452     }
453
454     private void setAuthoriserToReturnRequestIsAuthorized() throws IllegalAccessException {
455         AuthorizationResponse authResponse = mock(AuthorizationResponse.class);
456         Authorizer authorizer = mock(Authorizer.class);
457         FieldUtils.writeDeclaredStaticField(BaseServlet.class, "authz", authorizer, true);
458         when(authorizer.decide(request)).thenReturn(authResponse);
459         when(authResponse.isAuthorized()).thenReturn(true);
460     }
461
462     private void setUpValidAuthorisedRequest() throws Exception {
463         setUpValidSecurityOnHttpRequest();
464         setBehalfHeader("Stub_Value");
465         setValidPathInfoInHttpHeader();
466     }
467
468     private void setUpValidContentHeadersAndJSONOnHttpRequest() {
469         when(request.getHeader("Content-Type")).thenReturn("application/vnd.dmaap-dr.feed; version=1.0");
470         when(request.getHeader("X-DMAAP-DR-ON-BEHALF-OF-GROUP")).thenReturn("stub_subjectGroup");
471     }
472
473     private void reinsertFeedIntoDb() throws SQLException {
474         Feed feed = new Feed("Feed1","v0.1", "First Feed for testing", "First Feed for testing");
475         feed.setFeedid(1);
476         feed.setGroupid(1);
477         feed.setDeleted(false);
478         feed.doUpdate(db.getConnection());
479     }
480 }