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