Adding more DR-Node unit tests
[dmaap/datarouter.git] / datarouter-prov / src / test / java / org / onap / dmaap / datarouter / provisioning / SubscribeServletTest.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.JSONObject;
47 import org.junit.AfterClass;
48 import org.junit.Before;
49 import org.junit.BeforeClass;
50 import org.junit.Test;
51 import org.junit.runner.RunWith;
52 import org.mockito.Mock;
53 import org.onap.dmaap.datarouter.authz.AuthorizationResponse;
54 import org.onap.dmaap.datarouter.authz.Authorizer;
55 import org.onap.dmaap.datarouter.provisioning.beans.Insertable;
56 import org.onap.dmaap.datarouter.provisioning.utils.DB;
57 import org.powermock.modules.junit4.PowerMockRunner;
58
59
60 @RunWith(PowerMockRunner.class)
61 public class SubscribeServletTest extends DrServletTestBase {
62     private static SubscribeServlet subscribeServlet;
63     private static EntityManagerFactory emf;
64     private static EntityManager em;
65     private DB db;
66
67     @Mock
68     private HttpServletRequest request;
69     @Mock
70     private HttpServletResponse response;
71
72     private ListAppender<ILoggingEvent> listAppender;
73
74     @BeforeClass
75     public static void init() {
76         emf = Persistence.createEntityManagerFactory("dr-unit-tests");
77         em = emf.createEntityManager();
78         System.setProperty(
79                 "org.onap.dmaap.datarouter.provserver.properties",
80                 "src/test/resources/h2Database.properties");
81     }
82
83     @AfterClass
84     public static void tearDownClass() {
85         em.clear();
86         em.close();
87         emf.close();
88     }
89
90     @Before
91     public void setUp() throws Exception {
92         db = new DB();
93         listAppender = setTestLogger(SubscribeServlet.class);
94         subscribeServlet = new SubscribeServlet();
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         subscribeServlet.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() throws Exception {
111         when(request.isSecure()).thenReturn(false);
112         FieldUtils.writeDeclaredStaticField(BaseServlet.class, "isAddressAuthEnabled", "true", true);
113         subscribeServlet.doGet(request, response);
114         verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
115         verifyEnteringExitCalled(listAppender);
116     }
117
118     @Test
119     public void Given_Request_Is_HTTP_GET_And_BEHALF_HEADER_Is_Not_Set_In_Request_Then_Bad_Request_Response_Is_Generated() throws Exception {
120         setBehalfHeader(null);
121         subscribeServlet.doGet(request, response);
122         verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
123     }
124
125
126     @Test
127     public void Given_Request_Is_HTTP_GET_And_Path_Header_Is_Not_Set_In_Request_With_Valid_Path_Then_Bad_Request_Response_Is_Generated() throws Exception {
128         when(request.getPathInfo()).thenReturn(null);
129         subscribeServlet.doGet(request, response);
130         verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
131     }
132
133     @Test
134     public void Given_Request_Is_HTTP_GET_And_Feed_Id_Is_Invalid_Then_Not_Found_Response_Is_Generated() throws Exception {
135         when(request.getPathInfo()).thenReturn("/123");
136         subscribeServlet.doGet(request, response);
137         verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
138     }
139
140     @Test
141     public void Given_Request_Is_HTTP_GET_And_Request_Succeeds() throws Exception {
142         ServletOutputStream outStream = mock(ServletOutputStream.class);
143         when(response.getOutputStream()).thenReturn(outStream);
144         when(request.getPathInfo()).thenReturn("/1");
145         subscribeServlet.doGet(request, response);
146         verify(response).setStatus(eq(HttpServletResponse.SC_OK));
147         verifyEnteringExitCalled(listAppender);
148     }
149
150
151     @Test
152     public void Given_Request_Is_HTTP_PUT_SC_METHOD_NOT_ALLOWED_Response_Is_Generated() throws Exception {
153         subscribeServlet.doPut(request, response);
154         verify(response).sendError(eq(HttpServletResponse.SC_METHOD_NOT_ALLOWED), argThat(notNullValue(String.class)));
155         verifyEnteringExitCalled(listAppender);
156     }
157     @Test
158     public void Given_Request_Is_HTTP_POST_And_Is_Not_Secure_When_HTTPS_Is_Required_Then_Forbidden_Response_Is_Generated() throws Exception {
159         when(request.isSecure()).thenReturn(false);
160         FieldUtils.writeDeclaredStaticField(BaseServlet.class, "isAddressAuthEnabled", "true", true);
161         subscribeServlet.doPost(request, response);
162         verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
163         verifyEnteringExitCalled(listAppender);
164     }
165
166     @Test
167     public void Given_Request_Is_HTTP_POST_And_BEHALF_HEADER_Is_Not_Set_In_Request_Then_Bad_Request_Response_Is_Generated() throws Exception {
168         setBehalfHeader(null);
169         subscribeServlet.doPost(request, response);
170         verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
171     }
172
173
174     @Test
175     public void Given_Request_Is_HTTP_POST_And_Path_Header_Is_Not_Set_In_Request_With_Valid_Path_Then_Bad_Request_Response_Is_Generated() throws Exception {
176         when(request.getPathInfo()).thenReturn(null);
177         subscribeServlet.doPost(request, response);
178         verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
179     }
180
181
182     @Test
183     public void Given_Request_Is_HTTP_POST_And_Feed_Id_Is_Invalid_Then_Not_Found_Response_Is_Generated() throws Exception {
184         when(request.getPathInfo()).thenReturn("/123");
185         subscribeServlet.doPost(request, response);
186         verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
187     }
188
189     @Test
190     public void Given_Request_Is_HTTP_POST_And_Request_Is_Not_Authorized_Then_Forbidden_Response_Is_Generated() throws Exception {
191         setAuthoriserToReturnRequestNotAuthorized();
192         when(request.getPathInfo()).thenReturn("/1");
193         JSONObject JSObject = buildRequestJsonObject();
194         SubscribeServlet subscribeServlet = new SubscribeServlet() {
195             protected JSONObject getJSONfromInput(HttpServletRequest req) {
196                 JSONObject jo = new JSONObject();
197                 jo.put("name", "stub_name");
198                 jo.put("version", "2.0");
199                 jo.put("metadataOnly", true);
200                 jo.put("suspend", true);
201                 jo.put("delivery", JSObject);
202                 jo.put("sync", false);
203                 return jo;
204             }
205             @Override
206             protected boolean doInsert(Insertable bean) {
207                 return false;
208             }
209         };
210         subscribeServlet.doPost(request, response);
211         verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
212     }
213
214     @Test
215     public void Given_Request_Is_HTTP_POST_And_AAF_Subscriber_Added_To_Legacy_Feed_Then_Forbidden_Response_Is_Generated() throws Exception {
216         when(request.getPathInfo()).thenReturn("/1");
217         JSONObject JSObject = buildRequestJsonObject();
218         SubscribeServlet subscribeServlet = new SubscribeServlet() {
219             protected JSONObject getJSONfromInput(HttpServletRequest req) {
220                 JSONObject jo = new JSONObject();
221                 jo.put("name", "stub_name");
222                 jo.put("version", "2.0");
223                 jo.put("metadataOnly", true);
224                 jo.put("suspend", true);
225                 jo.put("delivery", JSObject);
226                 jo.put("aaf_instance", "*");
227                 jo.put("follow_redirect", false);
228                 jo.put("sync", false);
229                 return jo;
230             }
231             @Override
232             protected boolean doInsert(Insertable bean) {
233                 return false;
234             }
235         };
236         subscribeServlet.doPost(request, response);
237         verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), contains("AAF Subscriber can not be added to legacy Feed"));
238     }
239
240     @Test
241     public void Given_Request_Is_HTTP_POST_And_Legacy_Subscriber_Added_To_AAF_Feed_And_Is_Not_Authorized_Then_Forbidden_Response_Is_Generated() throws Exception {
242         setAuthoriserToReturnRequestNotAuthorized();
243         when(request.getPathInfo()).thenReturn("/2");
244         JSONObject JSObject = buildRequestJsonObject();
245         SubscribeServlet subscribeServlet = new SubscribeServlet() {
246             protected JSONObject getJSONfromInput(HttpServletRequest req) {
247                 JSONObject jo = new JSONObject();
248                 jo.put("name", "stub_name");
249                 jo.put("version", "2.0");
250                 jo.put("metadataOnly", true);
251                 jo.put("suspend", true);
252                 jo.put("delivery", JSObject);
253                 jo.put("aaf_instance", "legacy");
254                 jo.put("follow_redirect", false);
255                 jo.put("sync", false);
256                 return jo;
257             }
258         };
259         subscribeServlet.doPost(request, response);
260         verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), contains("Policy Engine disallows access."));
261     }
262
263     @Test
264     public void Given_Request_Is_HTTP_POST_And_AAF_Subscriber_Added_To_AAF_Feed_Without_Permissions_Then_Forbidden_Response_Is_Generated() throws Exception {
265         when(request.getPathInfo()).thenReturn("/2");
266         JSONObject JSObject = buildRequestJsonObject();
267         SubscribeServlet subscribeServlet = new SubscribeServlet() {
268             protected JSONObject getJSONfromInput(HttpServletRequest req) {
269                 JSONObject jo = new JSONObject();
270                 jo.put("name", "stub_name");
271                 jo.put("version", "2.0");
272                 jo.put("metadataOnly", true);
273                 jo.put("suspend", true);
274                 jo.put("delivery", JSObject);
275                 jo.put("aaf_instance", "*");
276                 jo.put("follow_redirect", false);
277                 jo.put("sync", false);
278                 return jo;
279             }
280         };
281         subscribeServlet.doPost(request, response);
282         verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), contains("AAF disallows access to permission"));
283     }
284
285     @Test
286     public void Given_Request_Is_HTTP_POST_And_AAF_Subscriber_Added_To_AAF_Feed_With_Permissions_Then_OK_Response_Is_Generated() throws Exception {
287         ServletOutputStream outStream = mock(ServletOutputStream.class);
288         when(response.getOutputStream()).thenReturn(outStream);
289         when(request.getPathInfo()).thenReturn("/2");
290         when(request.isUserInRole("org.onap.dmaap-dr.feed|*|approveSub")).thenReturn(true);
291         JSONObject JSObject = buildRequestJsonObject();
292         SubscribeServlet subscribeServlet = new SubscribeServlet() {
293             protected JSONObject getJSONfromInput(HttpServletRequest req) {
294                 JSONObject jo = new JSONObject();
295                 jo.put("name", "stub_name");
296                 jo.put("version", "2.0");
297                 jo.put("metadataOnly", true);
298                 jo.put("suspend", true);
299                 jo.put("delivery", JSObject);
300                 jo.put("aaf_instance", "*");
301                 jo.put("follow_redirect", false);
302                 jo.put("sync", false);
303                 return jo;
304             }
305
306             @Override
307             protected boolean doInsert(Insertable bean) {
308                 return true;
309             }
310         };
311         subscribeServlet.doPost(request, response);
312         verify(response).setStatus(eq(HttpServletResponse.SC_CREATED));
313         verifyEnteringExitCalled(listAppender);
314     }
315
316     @Test
317     public void Given_Request_Is_HTTP_POST_And_Content_Header_Is_Not_Supported_Type_Then_Unsupported_Media_Type_Response_Is_Generated() throws Exception {
318         when(request.getHeader("Content-Type")).thenReturn("application/vnd.dmaap-dr.feed; version=1.1");
319         when(request.getContentType()).thenReturn("stub_contentType");
320         when(request.getPathInfo()).thenReturn("/1");
321         subscribeServlet.doPost(request, response);
322         verify(response).sendError(eq(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE), argThat(notNullValue(String.class)));
323     }
324
325     @Test
326     public void Given_Request_Is_HTTP_POST_And_Request_Contains_Badly_Formed_JSON_Then_Bad_Request_Response_Is_Generated() throws Exception {
327         when(request.getPathInfo()).thenReturn("/1");
328         subscribeServlet.doPost(request, response);
329         verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
330     }
331
332     @Test
333     public void Given_Request_Is_HTTP_POST_And_Active_Feeds_Equals_Max_Feeds_Then_Bad_Request_Response_Is_Generated() throws Exception {
334         FieldUtils.writeDeclaredStaticField(BaseServlet.class, "maxSubs", 0, true);
335         when(request.getPathInfo()).thenReturn("/1");
336         SubscribeServlet subscribeServlet = new SubscribeServlet() {
337             protected JSONObject getJSONfromInput(HttpServletRequest req) {
338                 return new JSONObject();
339             }
340         };
341         subscribeServlet.doPost(request, response);
342         verify(response).sendError(eq(HttpServletResponse.SC_CONFLICT), argThat(notNullValue(String.class)));
343     }
344
345     @Test
346     public void Given_Request_Is_HTTP_POST_And_POST_Fails_Bad_Request_Response_Is_Generated() throws Exception {
347         when(request.getPathInfo()).thenReturn("/2");
348         JSONObject JSObject = buildRequestJsonObject();
349         SubscribeServlet subscribeServlet = new SubscribeServlet() {
350             protected JSONObject getJSONfromInput(HttpServletRequest req) {
351                 JSONObject jo = new JSONObject();
352                 jo.put("name", "stub_name");
353                 jo.put("version", "2.0");
354                 jo.put("metadataOnly", true);
355                 jo.put("suspend", true);
356                 jo.put("delivery", JSObject);
357                 jo.put("aaf_instance", "legacy");
358                 jo.put("follow_redirect", false);
359                 jo.put("sync", false);
360                 return jo;
361             }
362
363             @Override
364             protected boolean doInsert(Insertable bean) {
365                 return false;
366             }
367         };
368         subscribeServlet.doPost(request, response);
369         verify(response).sendError(eq(HttpServletResponse.SC_INTERNAL_SERVER_ERROR), argThat(notNullValue(String.class)));
370     }
371
372     @NotNull
373     private JSONObject buildRequestJsonObject() {
374         JSONObject JSObject = new JSONObject();
375         JSObject.put("url", "https://stub_address");
376         JSObject.put("use100", "true");
377         JSObject.put("password", "stub_password");
378         JSObject.put("user", "stub_user");
379         return JSObject;
380     }
381
382     private void setUpValidSecurityOnHttpRequest() throws Exception {
383         when(request.isSecure()).thenReturn(true);
384         Set<String> authAddressesAndNetworks = new HashSet<>();
385         authAddressesAndNetworks.add(("127.0.0.1"));
386         FieldUtils.writeDeclaredStaticField(BaseServlet.class, "authorizedAddressesAndNetworks", authAddressesAndNetworks, true);
387         FieldUtils.writeDeclaredStaticField(BaseServlet.class, "requireCert", false, true);
388         FieldUtils.writeDeclaredStaticField(BaseServlet.class, "maxSubs", 100, true);
389     }
390
391     private void setBehalfHeader(String headerValue) {
392         when(request.getHeader(BEHALF_HEADER)).thenReturn(headerValue);
393     }
394
395     private void setAuthoriserToReturnRequestNotAuthorized() throws IllegalAccessException {
396         AuthorizationResponse authResponse = mock(AuthorizationResponse.class);
397         Authorizer authorizer = mock(Authorizer.class);
398         FieldUtils.writeDeclaredStaticField(BaseServlet.class, "authz", authorizer, true);
399         when(authorizer.decide(request)).thenReturn(authResponse);
400         when(authResponse.isAuthorized()).thenReturn(false);
401     }
402
403     private void setAuthoriserToReturnRequestIsAuthorized() throws IllegalAccessException {
404         AuthorizationResponse authResponse = mock(AuthorizationResponse.class);
405         Authorizer authorizer = mock(Authorizer.class);
406         FieldUtils.writeDeclaredStaticField(BaseServlet.class, "authz", authorizer, true);
407         when(authorizer.decide(request)).thenReturn(authResponse);
408         when(authResponse.isAuthorized()).thenReturn(true);
409     }
410
411     private void setPokerToNotCreateTimersWhenDeleteFeedIsCalled() throws Exception {
412         Poker poker = mock(Poker.class);
413         FieldUtils.writeDeclaredStaticField(Poker.class, "poker", poker, true);
414     }
415
416     private void setupValidAuthorisedRequest() throws Exception {
417         setUpValidSecurityOnHttpRequest();
418         setBehalfHeader("Stub_Value");
419     }
420
421     private void setUpValidContentHeadersAndJSONOnHttpRequest() {
422         when(request.getHeader("Content-Type")).thenReturn("application/vnd.dmaap-dr.subscription; version=1.0");
423         when(request.getHeader("X-DMAAP-DR-ON-BEHALF-OF-GROUP")).thenReturn("stub_subjectGroup");
424
425     }
426 }