1 package org.onap.vid.controllers;
3 import com.google.common.collect.ImmutableMap;
4 import org.mockito.ArgumentCaptor;
5 import org.mockito.Mockito;
6 import org.mockito.stubbing.Answer;
7 import org.onap.portalsdk.core.web.support.UserUtils;
8 import org.onap.vid.controller.filter.PromiseEcompRequestIdFilter;
9 import org.springframework.mock.web.MockHttpServletResponse;
10 import org.testng.annotations.Test;
12 import javax.servlet.FilterChain;
13 import javax.servlet.ServletException;
14 import javax.servlet.ServletRequest;
15 import javax.servlet.ServletResponse;
16 import javax.servlet.http.HttpServletRequest;
17 import javax.servlet.http.HttpServletResponse;
18 import java.io.IOException;
20 import java.util.function.Function;
22 import static org.apache.commons.lang3.StringUtils.equalsIgnoreCase;
23 import static org.hamcrest.CoreMatchers.is;
24 import static org.hamcrest.MatcherAssert.assertThat;
25 import static org.hamcrest.Matchers.*;
26 import static org.mockito.ArgumentMatchers.any;
27 import static org.mockito.ArgumentMatchers.argThat;
28 import static org.onap.portalsdk.core.util.SystemProperties.ECOMP_REQUEST_ID;
31 public class PromiseEcompRequestIdFilterTest {
33 private final String anotherHeader = "ANDREI_RUBLEV";
34 private final String anotherValue = "foo value";
35 private final String mixedCaseHeader = "x-ecomp-REQUESTID";
38 public void givenRequestIdHeader_headerValueNotChanged() throws IOException, ServletException {
40 final String someTxId = "863850e2-8545-4efd-94b8-afba5f52b3d5";
42 final ImmutableMap<String, String> incomingRequestHeaders = ImmutableMap.of(
43 anotherHeader, anotherValue,
44 ECOMP_REQUEST_ID, someTxId
47 buildRequestThenRunThroughFilterAndAssertResultRequestHeaders(incomingRequestHeaders, specificTxId(someTxId));
51 public void givenMixedCaseRequestIdHeader_headerValueNotChanged() throws IOException, ServletException {
53 final String someTxId = "729bbd8d-b0c2-4809-a794-dcccd9cda2c0";
55 final ImmutableMap<String, String> incomingRequestHeaders = ImmutableMap.of(
56 mixedCaseHeader, someTxId,
57 anotherHeader, anotherValue
60 buildRequestThenRunThroughFilterAndAssertResultRequestHeaders(incomingRequestHeaders, specificTxId(someTxId));
64 public void givenNoRequestIdHeader_headerValueWasGenerated() throws IOException, ServletException {
66 final ImmutableMap<String, String> incomingRequestHeaders = ImmutableMap.of(
67 anotherHeader, anotherValue
70 buildRequestThenRunThroughFilterAndAssertResultRequestHeaders(incomingRequestHeaders, UserUtils::getRequestId);
74 private void buildRequestThenRunThroughFilterAndAssertResultRequestHeaders(
75 ImmutableMap<String, String> originalRequestHeaders,
76 Function<HttpServletRequest, String> txIdExtractor
77 ) throws IOException, ServletException {
78 HttpServletRequest servletRequest = createMockedHttpServletRequest(originalRequestHeaders);
79 HttpServletResponse servletResponse = createMockedHttpServletResponse();
81 final FilterChain capturingFilterChain = Mockito.mock(FilterChain.class);
85 // doFilter() is the function under test
87 new PromiseEcompRequestIdFilter().doFilter(servletRequest, servletResponse, capturingFilterChain);
91 final ServletRequest capturedServletRequest = extractCapturedServletRequest(capturingFilterChain);
92 final ServletResponse capturedServletResponse = extractCapturedServletResponse(capturingFilterChain);
93 final String expectedTxId = txIdExtractor.apply((HttpServletRequest) capturedServletRequest);
95 assertRequestObjectHeaders(capturedServletRequest, expectedTxId);
96 assertResponseObjectHeaders(capturedServletResponse, expectedTxId);
100 private void assertRequestObjectHeaders(ServletRequest request, String expectedTxId) {
103 - Two headers are in place
104 - Direct value extraction is as expected
105 - UserUtils.getRequestId() returns correct and valid value
107 final HttpServletRequest httpServletRequest = (HttpServletRequest) request;
109 assertThat(Collections.list(httpServletRequest.getHeaderNames()),
110 containsInAnyOrder(equalToIgnoringCase(ECOMP_REQUEST_ID), equalToIgnoringCase(anotherHeader)));
112 assertThat(httpServletRequest.getHeader(anotherHeader), is(anotherValue));
114 assertThat(httpServletRequest.getHeader(ECOMP_REQUEST_ID), is(expectedTxId));
115 assertThat(httpServletRequest.getHeader(mixedCaseHeader), is(expectedTxId));
117 assertThat(UserUtils.getRequestId(httpServletRequest), is(expectedTxId));
118 assertThat(UserUtils.getRequestId(httpServletRequest), is(not(emptyOrNullString())));
121 private void assertResponseObjectHeaders(ServletResponse response, String txId) {
122 final String REQUEST_ID_HEADER_NAME_IN_RESPONSE = mixedCaseHeader + "-echo";
123 final HttpServletResponse httpServletResponse = (HttpServletResponse) response;
125 assertThat("header " + REQUEST_ID_HEADER_NAME_IN_RESPONSE.toLowerCase() + " in response must be provided",
126 httpServletResponse.getHeader(REQUEST_ID_HEADER_NAME_IN_RESPONSE), is(txId));
131 private HttpServletRequest createMockedHttpServletRequest(Map<String, String> requestHeaders) {
132 HttpServletRequest servletRequest = Mockito.mock(HttpServletRequest.class);
133 requestHeaders.forEach((k, v) -> {
134 Mockito.when(servletRequest.getHeader(argThat(s -> equalsIgnoreCase(s, k)))).thenReturn(v);
135 Mockito.when(servletRequest.getHeaders(argThat(s -> equalsIgnoreCase(s, k)))).then(returnEnumerationAnswer(v));
137 Mockito.when(servletRequest.getHeaderNames()).then(returnEnumerationAnswer(requestHeaders.keySet()));
138 return servletRequest;
141 private HttpServletResponse createMockedHttpServletResponse() {
142 return new MockHttpServletResponse();
145 private static Answer<Enumeration<String>> returnEnumerationAnswer(String ... items) {
146 return returnEnumerationAnswer(Arrays.asList(items));
149 private static Answer<Enumeration<String>> returnEnumerationAnswer(Collection<String> items) {
150 return invocation -> Collections.enumeration(items);
153 private Function<HttpServletRequest, String> specificTxId(String someTxId) {
154 return r -> someTxId;
157 private ServletRequest extractCapturedServletRequest(FilterChain capturingFilterChain) throws IOException, ServletException {
158 ArgumentCaptor<ServletRequest> captor = ArgumentCaptor.forClass(ServletRequest.class);
159 Mockito.verify(capturingFilterChain).doFilter(captor.capture(), any());
160 return captor.getValue();
163 private ServletResponse extractCapturedServletResponse(FilterChain capturingFilterChain) throws IOException, ServletException {
164 ArgumentCaptor<ServletResponse> captor = ArgumentCaptor.forClass(ServletResponse.class);
165 Mockito.verify(capturingFilterChain).doFilter(any(), captor.capture());
166 return captor.getValue();