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.node;
25 import ch.qos.logback.classic.spi.ILoggingEvent;
26 import ch.qos.logback.core.read.ListAppender;
27 import ch.qos.logback.classic.Logger;
28 import org.apache.commons.lang3.reflect.FieldUtils;
30 import org.junit.runner.RunWith;
31 import org.mockito.Mock;
32 import org.powermock.api.mockito.PowerMockito;
33 import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor;
34 import org.powermock.modules.junit4.PowerMockRunner;
35 import org.slf4j.LoggerFactory;
37 import javax.servlet.http.HttpServletRequest;
38 import javax.servlet.http.HttpServletResponse;
42 import static org.hamcrest.Matchers.notNullValue;
43 import static org.junit.Assert.assertEquals;
44 import static org.mockito.Matchers.eq;
45 import static org.mockito.Mockito.*;
47 @RunWith(PowerMockRunner.class)
48 @SuppressStaticInitializationFor("org.onap.dmaap.datarouter.node.NodeConfigManager")
49 public class NodeServletTest {
51 private NodeServlet nodeServlet;
54 private HttpServletRequest request;
57 private HttpServletResponse response;
59 ListAppender<ILoggingEvent> listAppender;
62 public void setUp() throws Exception{
63 listAppender = setTestLogger();
64 nodeServlet = new NodeServlet();
65 setBehalfHeader("Stub_Value");
66 when(request.getPathInfo()).thenReturn("2");
67 when(request.isSecure()).thenReturn(true);
69 setUpNodeMainDelivery();
70 when(request.getHeader("Authorization")).thenReturn("User1");
71 when(request.getHeader("X-ATT-DR-PUBLISH-ID")).thenReturn("User1");
75 public void Given_Request_Is_HTTP_GET_And_Config_Is_Down_Then_Service_Unavailable_Response_Is_Generated() throws Exception {
76 setNodeConfigManagerIsConfiguredToReturnFalse();
77 nodeServlet.doGet(request, response);
78 verify(response).sendError(eq(HttpServletResponse.SC_SERVICE_UNAVAILABLE));
79 verifyEnteringExitCalled(listAppender);
83 public void Given_Request_Is_HTTP_GET_And_Endpoint_Is_Internal_FetchProv_Then_No_Content_Response_Is_Generated() throws Exception {
84 when(request.getPathInfo()).thenReturn("/internal/fetchProv");
85 nodeServlet.doGet(request, response);
86 verify(response).setStatus(eq(HttpServletResponse.SC_NO_CONTENT));
87 verifyEnteringExitCalled(listAppender);
91 public void Given_Request_Is_HTTP_GET_And_Endpoint_Is_ResetSubscription_Then_No_Content_Response_Is_Generated() throws Exception {
92 when(request.getPathInfo()).thenReturn("/internal/resetSubscription/1");
93 nodeServlet.doGet(request, response);
94 verify(response).setStatus(eq(HttpServletResponse.SC_NO_CONTENT));
95 verifyEnteringExitCalled(listAppender);
99 public void Given_Request_Is_HTTP_GET_To_Invalid_Endpoint_Then_Not_Found_Response_Is_Generated() throws Exception {
100 when(request.getPathInfo()).thenReturn("/incorrect");
101 nodeServlet.doGet(request, response);
102 verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND));
103 verifyEnteringExitCalled(listAppender);
107 public void Given_Request_Is_HTTP_PUT_And_Config_Is_Down_Then_Service_Unavailable_Response_Is_Generated() throws Exception {
108 setNodeConfigManagerIsConfiguredToReturnFalse();
109 nodeServlet.doPut(request, response);
110 verify(response).sendError(eq(HttpServletResponse.SC_SERVICE_UNAVAILABLE));
111 verifyEnteringExitCalled(listAppender);
115 public void Given_Request_Is_HTTP_PUT_And_Endpoint_Is_Incorrect_Then_Not_Found_Response_Is_Generated() throws Exception {
116 when(request.getPathInfo()).thenReturn("/incorrect/");
117 nodeServlet.doPut(request, response);
118 verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
119 verifyEnteringExitCalled(listAppender);
123 public void Given_Request_Is_HTTP_PUT_And_Request_Is_Not_Secure_Then_Forbidden_Response_Is_Generated() throws Exception {
124 when(request.isSecure()).thenReturn(false);
125 nodeServlet.doPut(request, response);
126 verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
127 verifyEnteringExitCalled(listAppender);
131 public void Given_Request_Is_HTTP_PUT_And_File_Id_Is_Null_Then_Not_Found_Response_Is_Generated() throws Exception {
132 when(request.getPathInfo()).thenReturn(null);
133 nodeServlet.doPut(request, response);
134 verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
135 verifyEnteringExitCalled(listAppender);
139 public void Given_Request_Is_HTTP_PUT_And_Authorization_Is_Null_Then_Forbidden_Response_Is_Generated() throws Exception {
140 when(request.getHeader("Authorization")).thenReturn(null);
141 nodeServlet.doPut(request, response);
142 verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
143 verifyEnteringExitCalled(listAppender);
147 public void Given_Request_Is_HTTP_PUT_And_Publish_Does_Not_Include_File_Id_Then_Not_Found_Response_Is_Generated() throws Exception {
148 when(request.getPathInfo()).thenReturn("/publish/");
149 nodeServlet.doPut(request, response);
150 verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
151 verifyEnteringExitCalled(listAppender);
155 public void Given_Request_Is_HTTP_PUT_And_Publish_Not_Permitted_Then_Forbidden_Response_Is_Generated() throws Exception {
156 when(request.getPathInfo()).thenReturn("/publish/1/fileName");
157 setNodeConfigManagerIsPublishPermittedToReturnAReason();
158 nodeServlet.doPut(request, response);
159 verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
160 verifyEnteringExitCalled(listAppender);
164 public void Given_Request_Is_HTTP_PUT_And_Internal_Publish_On_Same_Node_Then_Forbidden_Response_Is_Generated() throws Exception {
165 when(request.getPathInfo()).thenReturn("/internal/publish/1/fileName");
166 setNodeConfigManagerIsPublishPermittedToReturnAReason();
167 nodeServlet.doPut(request, response);
168 verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN));
169 verifyEnteringExitCalled(listAppender);
173 public void Given_Request_Is_HTTP_PUT_And_Internal_Publish_But_Invalid_File_Id_Then_Not_Found_Response_Is_Generated() throws Exception {
174 when(request.getPathInfo()).thenReturn("/internal/publish/1/");
175 nodeServlet.doPut(request, response);
176 verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
177 verifyEnteringExitCalled(listAppender);
181 public void Given_Request_Is_HTTP_PUT_On_Publish_And_Ingress_Node_Is_Provided_Then_Request_Is_Redirected() throws Exception {
182 when(request.getPathInfo()).thenReturn("/publish/1/fileName");
183 setNodeConfigManagerToAllowRedirectOnIngressNode();
184 nodeServlet.doPut(request, response);
185 verify(response).sendRedirect(anyString());
186 verifyEnteringExitCalled(listAppender);
190 public void Given_Request_Is_HTTP_PUT_On_Publish_With_Meta_Data_Too_Long_Then_Bad_Request_Response_Is_Generated() throws Exception {
191 when(request.getPathInfo()).thenReturn("/publish/1/fileName");
192 setHeadersForValidRequest(true);
193 nodeServlet.doPut(request, response);
194 verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
195 verifyEnteringExitCalled(listAppender);
199 public void Given_Request_Is_HTTP_PUT_On_Publish_With_Meta_Data_Malformed_Then_Bad_Request_Response_Is_Generated() throws Exception {
200 when(request.getPathInfo()).thenReturn("/publish/1/fileName");
201 setHeadersForValidRequest(false);
202 nodeServlet.doPut(request, response);
203 verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
204 verifyEnteringExitCalled(listAppender);
208 public void Given_Request_Is_HTTP_DELETE_On_Publish_With_Meta_Data_Malformed_Then_Bad_Request_Response_Is_Generated() throws Exception {
209 when(request.getPathInfo()).thenReturn("/publish/1/fileName");
210 setHeadersForValidRequest(false);
211 nodeServlet.doDelete(request, response);
212 verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
213 verifyEnteringExitCalled(listAppender);
217 private void setBehalfHeader(String headerValue) {
218 when(request.getHeader("X-ATT-DR-ON-BEHALF-OF")).thenReturn(headerValue);
221 private ListAppender<ILoggingEvent> setTestLogger() {
222 Logger Logger = (Logger) LoggerFactory.getLogger(NodeServlet.class);
223 ListAppender<ILoggingEvent> listAppender = new ListAppender<>();
224 listAppender.start();
225 Logger.addAppender(listAppender);
229 private void verifyEnteringExitCalled(ListAppender<ILoggingEvent> listAppender) {
230 assertEquals("EELF0004I Entering data router node component with RequestId and InvocationId", listAppender.list.get(0).getMessage());
231 assertEquals("EELF0005I Exiting data router node component with RequestId and InvocationId", listAppender.list.get(2).getMessage());
232 assertEquals(3, listAppender.list.size());
235 private void setUpConfig() throws IllegalAccessException{
236 NodeConfigManager config = mock(NodeConfigManager.class);
237 PowerMockito.mockStatic(NodeConfigManager.class);
238 when(config.isShutdown()).thenReturn(false);
239 when(config.isConfigured()).thenReturn(true);
240 when(config.getSpoolDir()).thenReturn("spool/dir");
241 when(config.getLogDir()).thenReturn("log/dir");
242 when(config.getPublishId()).thenReturn("User1");
243 when(config.isAnotherNode(anyString(), anyString())).thenReturn(true);
244 when(config.getEventLogInterval()).thenReturn("40");
245 FieldUtils.writeDeclaredStaticField(NodeServlet.class, "config", config, true);
246 FieldUtils.writeDeclaredStaticField(NodeMain.class, "nodeConfigManager", config, true);
247 PowerMockito.when(NodeConfigManager.getInstance()).thenReturn(config);
251 private void setUpNodeMainDelivery() throws IllegalAccessException{
252 Delivery delivery = mock(Delivery.class);
253 doNothing().when(delivery).resetQueue(anyObject());
254 FieldUtils.writeDeclaredStaticField(NodeMain.class, "delivery", delivery, true);
257 private void setNodeConfigManagerIsConfiguredToReturnFalse() throws IllegalAccessException{
258 NodeConfigManager config = mock(NodeConfigManager.class);
259 when(config.isConfigured()).thenReturn(false);
260 FieldUtils.writeDeclaredStaticField(NodeServlet.class, "config", config, true);
263 private void setNodeConfigManagerIsPublishPermittedToReturnAReason() throws IllegalAccessException{
264 NodeConfigManager config = mock(NodeConfigManager.class);
265 when(config.isShutdown()).thenReturn(false);
266 when(config.isConfigured()).thenReturn(true);
267 when(config.getSpoolDir()).thenReturn("spool/dir");
268 when(config.getLogDir()).thenReturn("log/dir");
269 when(config.isPublishPermitted(anyString(), anyString(), anyString())).thenReturn("Not Permitted");
270 when(config.isAnotherNode(anyString(), anyString())).thenReturn(false);
271 FieldUtils.writeDeclaredStaticField(NodeServlet.class, "config", config, true);
274 private void setNodeConfigManagerToAllowRedirectOnIngressNode() throws IllegalAccessException{
275 NodeConfigManager config = mock(NodeConfigManager.class);
276 when(config.isShutdown()).thenReturn(false);
277 when(config.isConfigured()).thenReturn(true);
278 when(config.getSpoolDir()).thenReturn("spool/dir");
279 when(config.getLogDir()).thenReturn("log/dir");
280 when(config.getPublishId()).thenReturn("User1");
281 when(config.isAnotherNode(anyString(), anyString())).thenReturn(true);
282 when(config.getAuthUser(anyString(), anyString())).thenReturn("User1");
283 when(config.getIngressNode(anyString(), anyString(), anyString())).thenReturn("NewNode");
284 when(config.getExtHttpsPort()).thenReturn(8080);
285 FieldUtils.writeDeclaredStaticField(NodeServlet.class, "config", config, true);
288 private String createLargeMetaDataString() {
289 StringBuilder myString = new StringBuilder("meta");
290 for (int i = 0; i <= 4098; ++i) {
291 myString.append('x');
293 return myString.toString();
296 private void setHeadersForValidRequest(boolean isMetaTooLong) {
297 String metaDataString;
299 metaDataString = createLargeMetaDataString();
301 metaDataString = "?#@><";
303 List<String> headers = new ArrayList<>();
304 headers.add("Content-Type");
305 headers.add("X-ATT-DR-ON-BEHALF-OF");
306 headers.add("X-ATT-DR-META");
307 Enumeration<String> headerNames = Collections.enumeration(headers);
308 when(request.getHeaderNames()).thenReturn(headerNames);
309 Enumeration<String> contentTypeHeader = Collections.enumeration(Arrays.asList("text/plain"));
310 Enumeration<String> behalfHeader = Collections.enumeration(Arrays.asList("User1"));
311 Enumeration<String> metaDataHeader = Collections.enumeration(Arrays.asList(metaDataString));
312 when(request.getHeaders("Content-Type")).thenReturn(contentTypeHeader);
313 when(request.getHeaders("X-ATT-DR-ON-BEHALF-OF")).thenReturn(behalfHeader);
314 when(request.getHeaders("X-ATT-DR-META")).thenReturn(metaDataHeader);