2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 - 2019 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=========================================================
21 package org.onap.vid.mso.rest;
23 import static org.apache.commons.lang3.StringUtils.equalsIgnoreCase;
24 import static org.hamcrest.MatcherAssert.assertThat;
25 import static org.hamcrest.Matchers.allOf;
26 import static org.hamcrest.Matchers.hasItem;
27 import static org.hamcrest.Matchers.hasToString;
28 import static org.hamcrest.Matchers.instanceOf;
29 import static org.hamcrest.Matchers.matchesPattern;
30 import static org.mockito.Mockito.when;
32 import com.google.common.collect.ImmutableList;
34 import java.util.UUID;
35 import java.util.function.Consumer;
36 import java.util.stream.Collectors;
37 import java.util.stream.Stream;
38 import javax.servlet.http.HttpServletRequest;
39 import javax.ws.rs.client.Client;
40 import javax.ws.rs.client.Invocation;
41 import javax.ws.rs.core.MultivaluedMap;
42 import org.apache.commons.lang3.reflect.FieldUtils;
43 import org.mockito.ArgumentCaptor;
44 import org.mockito.Captor;
45 import org.mockito.InjectMocks;
46 import org.mockito.Matchers;
47 import org.mockito.Mock;
48 import org.mockito.Mockito;
49 import org.mockito.MockitoAnnotations;
50 import org.onap.vid.aai.util.AAIRestInterface;
51 import org.onap.vid.aai.util.ServletRequestHelper;
52 import org.onap.vid.aai.util.SystemPropertyHelper;
53 import org.onap.vid.controller.filter.PromiseEcompRequestIdFilter;
54 import org.onap.vid.testUtils.TestUtils;
55 import org.onap.vid.utils.Unchecked;
56 import org.springframework.mock.web.MockHttpServletRequest;
57 import org.springframework.web.context.request.RequestContextHolder;
58 import org.springframework.web.context.request.ServletRequestAttributes;
59 import org.testng.annotations.BeforeClass;
60 import org.testng.annotations.BeforeMethod;
61 import org.testng.annotations.DataProvider;
62 import org.testng.annotations.Test;
65 public class OutgoingRequestHeadersTest {
69 // private RestMsoImplementation restMsoImplementation;
72 private SystemPropertyHelper systemPropertyHelper;
75 private ServletRequestHelper servletRequestHelper;
78 private AAIRestInterface aaiRestInterface;
81 private ArgumentCaptor<MultivaluedMap<String, Object>> multivaluedMapArgumentCaptor;
84 public void initMocks() {
85 MockitoAnnotations.initMocks(this);
86 when(servletRequestHelper.extractOrGenerateRequestId()).thenAnswer(invocation -> UUID.randomUUID().toString());
90 private void setup() {
91 putRequestInSpringContext();
94 public static void putRequestInSpringContext() {
95 RequestContextHolder.setRequestAttributes(new ServletRequestAttributes((HttpServletRequest) PromiseEcompRequestIdFilter.wrapIfNeeded(new MockHttpServletRequest())));
99 // public Object[][] msoMethods() {
100 // return Stream.<ThrowingConsumer<RestMsoImplementation>>of(
102 // client -> client.Get(new Object(), "/any path", new RestObject<>(), false),
103 // client -> client.GetForObject("/any path", Object.class),
104 // client -> client.Post("", "some payload", "/any path", new RestObject<>()),
105 // client -> client.PostForObject("some payload", "/any path", Object.class),
106 // client -> client.Put(Object.class, new RequestDetailsWrapper(), "/any path", new RestObject<>())
108 // ).map(l -> ImmutableList.of(l).toArray()).collect(Collectors.toList()).toArray(new Object[][]{});
111 // @Test(dataProvider = "msoMethods")
112 // public void mso(Consumer<RestMsoImplementation> f) throws Exception {
113 // final TestUtils.JavaxRsClientMocks mocks = setAndGetMocksInsideRestImpl(restMsoImplementation);
115 // f.accept(restMsoImplementation);
117 // Invocation.Builder fakeBuilder = mocks.getFakeBuilder();
118 // Object requestIdValue = verifyXEcompRequestIdHeaderWasAdded(fakeBuilder);
119 // assertEquals(requestIdValue, captureHeaderKeyAndReturnItsValue(fakeBuilder, "X-ONAP-RequestID"));
121 // assertThat((String) captureHeaderKeyAndReturnItsValue(fakeBuilder, "Authorization"), startsWith("Basic "));
122 // assertThat(captureHeaderKeyAndReturnItsValue(fakeBuilder, "X-ONAP-PartnerName"), equalTo("VID"));
126 // public void whenProvideMsoRestCallUserId_builderHasXRequestorIDHeader() throws Exception {
128 // final TestUtils.JavaxRsClientMocks mocks = setAndGetMocksInsideRestImpl(restMsoImplementation);
129 // String randomUserName = randomAlphabetic(10);
131 // restMsoImplementation.restCall(HttpMethod.DELETE, String.class, null, "abc", Optional.of(randomUserName));
132 // assertEquals(randomUserName, captureHeaderKeyAndReturnItsValue(mocks.getFakeBuilder(), "X-RequestorID"));
136 public Object[][] aaiMethods() {
137 return Stream.<ThrowingConsumer<AAIRestInterface>>of(
139 client -> client.RestGet("from app id", "some transId", Unchecked.toURI("/any path"), false),
140 client -> client.Delete("whatever source id", "some transId", "/any path"),
141 client -> client.RestPost("from app id", "/any path", "some payload", false),
142 client -> client.RestPut("from app id", "/any path", "some payload", false, false)
144 ).map(l -> ImmutableList.of(l).toArray()).collect(Collectors.toList()).toArray(new Object[][]{});
147 @Test(dataProvider = "aaiMethods")
148 public void aai(Consumer<AAIRestInterface> f) throws Exception {
149 final TestUtils.JavaxRsClientMocks mocks = setAndGetMocksInsideRestImpl(aaiRestInterface);
151 f.accept(aaiRestInterface);
153 verifyXEcompRequestIdHeaderWasAdded(mocks.getFakeBuilder());
156 // @Test(dataProvider = "schedulerMethods")
157 // public void scheduler(Consumer<AAIRestInterface> f) throws Exception {
159 // This test os not feasible in the wat acheduler is implemented today,
160 // as Scheduler's client is rewritten in every call.
166 private Object verifyXEcompRequestIdHeaderWasAdded(Invocation.Builder fakeBuilder) {
167 final String requestIdHeader = "x-ecomp-requestid";
168 final String uuidRegex = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}";
169 Object requestId = captureHeaderKeyAndReturnItsValue(fakeBuilder, requestIdHeader);
171 assertThat("header '" + requestIdHeader + "' should be a uuid", requestId,
172 allOf(instanceOf(String.class), hasToString(matchesPattern(uuidRegex))));
176 private Object captureHeaderKeyAndReturnItsValue(Invocation.Builder fakeBuilder, String headerName) {
177 // Checks that the builder was called with either one of header("x-ecomp-requestid", uuid)
178 // or the plural brother: headers(Map.of("x-ecomp-requestid", Set.of(uuid))
181 // The 'verify()' will capture the request id. If no match -- AssertionError will
182 // catch for a second chance -- another 'verify()'.
184 ArgumentCaptor<Object> argumentCaptor = ArgumentCaptor.forClass(Object.class);
185 Mockito.verify(fakeBuilder)
187 Matchers.argThat(s -> equalsIgnoreCase(s, headerName)),
188 argumentCaptor.capture()
190 requestId = argumentCaptor.getValue();
192 } catch (AssertionError e) {
193 Mockito.verify(fakeBuilder).headers(multivaluedMapArgumentCaptor.capture());
195 final MultivaluedMap<String, Object> headersMap = multivaluedMapArgumentCaptor.getValue();
196 final String thisRequestIdHeader = getFromSetCaseInsensitive(headersMap.keySet(), headerName);
198 assertThat(headersMap.keySet(), hasItem(thisRequestIdHeader));
199 requestId = headersMap.getFirst(thisRequestIdHeader);
204 private String getFromSetCaseInsensitive(Set<String> set, String key) {
206 .filter(anotherString -> anotherString.equalsIgnoreCase(key))
211 private TestUtils.JavaxRsClientMocks setAndGetMocksInsideRestImpl(Class<?> clazz) throws IllegalAccessException {
212 TestUtils.JavaxRsClientMocks mocks = new TestUtils.JavaxRsClientMocks();
213 Client fakeClient = mocks.getFakeClient();
215 FieldUtils.writeStaticField(clazz, "client", fakeClient, true);
220 private TestUtils.JavaxRsClientMocks setAndGetMocksInsideRestImpl(Object instance) throws IllegalAccessException {
221 TestUtils.JavaxRsClientMocks mocks = new TestUtils.JavaxRsClientMocks();
222 Client fakeClient = mocks.getFakeClient();
224 FieldUtils.writeField(instance, "client", fakeClient, true);
230 public interface ThrowingConsumer<T> extends Consumer<T> {
232 default void accept(T t) {
235 } catch (Exception e) {
236 throw new RuntimeException(e);
240 void acceptThrows(T t) throws Exception;