/*- | |
* ============LICENSE_START======================================================= | |
* OSAM | |
* ================================================================================ | |
* Copyright (C) 2018 AT&T | |
* ================================================================================ | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
* ============LICENSE_END========================================================= | |
*/ | |
package org.onap.osam.controllers; | |
import com.google.common.collect.ImmutableMap; | |
import org.mockito.ArgumentCaptor; | |
import org.mockito.Mockito; | |
import org.mockito.stubbing.Answer; | |
import org.onap.portalsdk.core.web.support.UserUtils; | |
import org.onap.osam.filters.PromiseEcompRequestIdFilter; | |
import org.springframework.mock.web.MockHttpServletResponse; | |
import org.testng.annotations.Test; | |
import javax.servlet.FilterChain; | |
import javax.servlet.ServletException; | |
import javax.servlet.ServletRequest; | |
import javax.servlet.ServletResponse; | |
import javax.servlet.http.HttpServletRequest; | |
import javax.servlet.http.HttpServletResponse; | |
import java.io.IOException; | |
import java.util.*; | |
import java.util.function.Function; | |
import static org.hamcrest.CoreMatchers.is; | |
import static org.hamcrest.MatcherAssert.assertThat; | |
import static org.hamcrest.Matchers.*; | |
import static org.mockito.Matchers.any; | |
import static org.mockito.Matchers.argThat; | |
import static org.onap.portalsdk.core.util.SystemProperties.ECOMP_REQUEST_ID; | |
@Test | |
public class PromiseEcompRequestIdFilterTest { | |
private final String anotherHeader = "ANDREI_RUBLEV"; | |
private final String anotherValue = "foo value"; | |
private final String mixedCaseHeader = "x-ecomp-REQUESTID"; | |
@Test | |
public void givenRequestIdHeader_headerValueNotChanged() throws IOException, ServletException { | |
final String someTxId = "863850e2-8545-4efd-94b8-afba5f52b3d5"; | |
final ImmutableMap<String, String> incomingRequestHeaders = ImmutableMap.of( | |
anotherHeader, anotherValue, | |
ECOMP_REQUEST_ID, someTxId | |
); | |
buildRequestThenRunThroughFilterAndAssertResultRequestHeaders(incomingRequestHeaders, specificTxId(someTxId)); | |
} | |
@Test | |
public void givenMixedCaseRequestIdHeader_headerValueNotChanged() throws IOException, ServletException { | |
final String someTxId = "729bbd8d-b0c2-4809-a794-dcccd9cda2c0"; | |
final ImmutableMap<String, String> incomingRequestHeaders = ImmutableMap.of( | |
mixedCaseHeader, someTxId, | |
anotherHeader, anotherValue | |
); | |
buildRequestThenRunThroughFilterAndAssertResultRequestHeaders(incomingRequestHeaders, specificTxId(someTxId)); | |
} | |
@Test | |
public void givenNoRequestIdHeader_headerValueWasGenerated() throws IOException, ServletException { | |
final ImmutableMap<String, String> incomingRequestHeaders = ImmutableMap.of( | |
anotherHeader, anotherValue | |
); | |
buildRequestThenRunThroughFilterAndAssertResultRequestHeaders(incomingRequestHeaders, UserUtils::getRequestId); | |
} | |
private void buildRequestThenRunThroughFilterAndAssertResultRequestHeaders( | |
ImmutableMap<String, String> originalRequestHeaders, | |
Function<HttpServletRequest, String> txIdExtractor | |
) throws IOException, ServletException { | |
HttpServletRequest servletRequest = createMockedHttpServletRequest(originalRequestHeaders); | |
HttpServletResponse servletResponse = createMockedHttpServletResponse(); | |
final FilterChain capturingFilterChain = Mockito.mock(FilterChain.class); | |
////////////////// | |
// | |
// doFilter() is the function under test | |
// | |
new PromiseEcompRequestIdFilter().doFilter(servletRequest, servletResponse, capturingFilterChain); | |
// | |
////////////////// | |
final ServletRequest capturedServletRequest = extractCapturedServletRequest(capturingFilterChain); | |
final ServletResponse capturedServletResponse = extractCapturedServletResponse(capturingFilterChain); | |
final String expectedTxId = txIdExtractor.apply((HttpServletRequest) capturedServletRequest); | |
assertRequestObjectHeaders(capturedServletRequest, expectedTxId); | |
assertResponseObjectHeaders(capturedServletResponse, expectedTxId); | |
} | |
private void assertRequestObjectHeaders(ServletRequest request, String expectedTxId) { | |
final HttpServletRequest httpServletRequest = (HttpServletRequest) request; | |
assertThat(Collections.list(httpServletRequest.getHeaderNames()), | |
containsInAnyOrder(equalToIgnoringCase(ECOMP_REQUEST_ID), equalToIgnoringCase(anotherHeader))); | |
assertThat(httpServletRequest.getHeader(anotherHeader), is(anotherValue)); | |
assertThat(httpServletRequest.getHeader(ECOMP_REQUEST_ID), is(expectedTxId)); | |
assertThat(httpServletRequest.getHeader(mixedCaseHeader), is(expectedTxId)); | |
assertThat(UserUtils.getRequestId(httpServletRequest), is(expectedTxId)); | |
assertThat(UserUtils.getRequestId(httpServletRequest), is(not(emptyOrNullString()))); | |
} | |
private void assertResponseObjectHeaders(ServletResponse response, String txId) { | |
final String REQUEST_ID_HEADER_NAME_IN_RESPONSE = mixedCaseHeader + "-echo"; | |
final HttpServletResponse httpServletResponse = (HttpServletResponse) response; | |
assertThat("header " + REQUEST_ID_HEADER_NAME_IN_RESPONSE.toLowerCase() + " in response must be provided", | |
httpServletResponse.getHeader(REQUEST_ID_HEADER_NAME_IN_RESPONSE), is(txId)); | |
} | |
private HttpServletRequest createMockedHttpServletRequest(Map<String, String> requestHeaders) { | |
HttpServletRequest servletRequest = Mockito.mock(HttpServletRequest.class); | |
requestHeaders.forEach((k, v) -> { | |
Mockito.when(servletRequest.getHeader(argThat(equalToIgnoringCase(k)))).thenReturn(v); | |
Mockito.when(servletRequest.getHeaders(argThat(equalToIgnoringCase(k)))).then(returnEnumerationAnswer(v)); | |
}); | |
Mockito.when(servletRequest.getHeaderNames()).then(returnEnumerationAnswer(requestHeaders.keySet())); | |
return servletRequest; | |
} | |
private HttpServletResponse createMockedHttpServletResponse() { | |
return new MockHttpServletResponse(); | |
} | |
private static Answer<Enumeration<String>> returnEnumerationAnswer(String ... items) { | |
return returnEnumerationAnswer(Arrays.asList(items)); | |
} | |
private static Answer<Enumeration<String>> returnEnumerationAnswer(Collection<String> items) { | |
return invocation -> Collections.enumeration(items); | |
} | |
private Function<HttpServletRequest, String> specificTxId(String someTxId) { | |
return r -> someTxId; | |
} | |
private ServletRequest extractCapturedServletRequest(FilterChain capturingFilterChain) throws IOException, ServletException { | |
ArgumentCaptor<ServletRequest> captor = ArgumentCaptor.forClass(ServletRequest.class); | |
Mockito.verify(capturingFilterChain).doFilter(captor.capture(), any()); | |
return captor.getValue(); | |
} | |
private ServletResponse extractCapturedServletResponse(FilterChain capturingFilterChain) throws IOException, ServletException { | |
ArgumentCaptor<ServletResponse> captor = ArgumentCaptor.forClass(ServletResponse.class); | |
Mockito.verify(capturingFilterChain).doFilter(any(), captor.capture()); | |
return captor.getValue(); | |
} | |
} |