1 /*******************************************************************************
2 * ============LICENSE_START==================================================
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
11 * * http://www.apache.org/licenses/LICENSE-2.0
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====================================================
20 * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22 ******************************************************************************/
23 package org.onap.dmaap.datarouter.provisioning;
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;
34 import ch.qos.logback.classic.spi.ILoggingEvent;
35 import ch.qos.logback.core.read.ListAppender;
36 import java.util.HashSet;
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;
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;
68 private HttpServletRequest request;
70 private HttpServletResponse response;
72 private ListAppender<ILoggingEvent> listAppender;
75 public static void init() {
76 emf = Persistence.createEntityManagerFactory("dr-unit-tests");
77 em = emf.createEntityManager();
79 "org.onap.dmaap.datarouter.provserver.properties",
80 "src/test/resources/h2Database.properties");
84 public static void tearDownClass() {
91 public void setUp() throws Exception {
93 listAppender = setTestLogger(SubscribeServlet.class);
94 subscribeServlet = new SubscribeServlet();
95 setAuthoriserToReturnRequestIsAuthorized();
96 setPokerToNotCreateTimersWhenDeleteFeedIsCalled();
97 setupValidAuthorisedRequest();
98 setUpValidSecurityOnHttpRequest();
99 setUpValidContentHeadersAndJSONOnHttpRequest();
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);
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);
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)));
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)));
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)));
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);
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);
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);
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)));
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)));
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)));
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);
206 protected boolean doInsert(Insertable bean) {
210 subscribeServlet.doPost(request, response);
211 verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
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);
232 protected boolean doInsert(Insertable bean) {
236 subscribeServlet.doPost(request, response);
237 verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), contains("AAF Subscriber can not be added to legacy Feed"));
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);
259 subscribeServlet.doPost(request, response);
260 verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), contains("Policy Engine disallows access."));
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);
281 subscribeServlet.doPost(request, response);
282 verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), contains("AAF disallows access to permission"));
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);
307 protected boolean doInsert(Insertable bean) {
311 subscribeServlet.doPost(request, response);
312 verify(response).setStatus(eq(HttpServletResponse.SC_CREATED));
313 verifyEnteringExitCalled(listAppender);
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)));
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)));
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();
341 subscribeServlet.doPost(request, response);
342 verify(response).sendError(eq(HttpServletResponse.SC_CONFLICT), argThat(notNullValue(String.class)));
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);
364 protected boolean doInsert(Insertable bean) {
368 subscribeServlet.doPost(request, response);
369 verify(response).sendError(eq(HttpServletResponse.SC_INTERNAL_SERVER_ERROR), argThat(notNullValue(String.class)));
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");
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);
391 private void setBehalfHeader(String headerValue) {
392 when(request.getHeader(BEHALF_HEADER)).thenReturn(headerValue);
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);
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);
411 private void setPokerToNotCreateTimersWhenDeleteFeedIsCalled() throws Exception {
412 Poker poker = mock(Poker.class);
413 FieldUtils.writeDeclaredStaticField(Poker.class, "poker", poker, true);
416 private void setupValidAuthorisedRequest() throws Exception {
417 setUpValidSecurityOnHttpRequest();
418 setBehalfHeader("Stub_Value");
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");