3ea025870b0ced2f11075db5cdc15ee974df4e8d
[vid.git] / vid-app-common / src / test / java / org / onap / vid / mso / rest / OutgoingRequestHeadersTest.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * VID
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
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
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=========================================================
19  */
20
21 package org.onap.vid.mso.rest;
22
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;
31
32 import com.google.common.collect.ImmutableList;
33 import java.util.Set;
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.PromiseRequestIdFilter;
54 import org.onap.vid.logging.Headers;
55 import org.onap.vid.testUtils.TestUtils;
56 import org.onap.vid.utils.Logging;
57 import org.onap.vid.utils.Unchecked;
58 import org.springframework.mock.web.MockHttpServletRequest;
59 import org.springframework.web.context.request.RequestContextHolder;
60 import org.springframework.web.context.request.ServletRequestAttributes;
61 import org.testng.annotations.BeforeClass;
62 import org.testng.annotations.BeforeMethod;
63 import org.testng.annotations.DataProvider;
64 import org.testng.annotations.Test;
65
66
67 public class OutgoingRequestHeadersTest {
68
69     private static final PromiseRequestIdFilter promiseRequestIdFilter =
70         new PromiseRequestIdFilter(new Headers());
71
72 //    @InjectMocks
73 //    private RestMsoImplementation restMsoImplementation;
74
75     @Mock
76     private SystemPropertyHelper systemPropertyHelper;
77
78     @Mock
79     private ServletRequestHelper servletRequestHelper;
80
81     @Mock
82     private Logging loggingService;
83
84     @InjectMocks
85     private AAIRestInterface aaiRestInterface;
86
87     @Captor
88     private ArgumentCaptor<MultivaluedMap<String, Object>> multivaluedMapArgumentCaptor;
89
90     @BeforeClass
91     public void initMocks() {
92         MockitoAnnotations.initMocks(this);
93         when(servletRequestHelper.extractOrGenerateRequestId()).thenAnswer(invocation -> UUID.randomUUID().toString());
94     }
95
96     @BeforeMethod
97     private void setup() {
98         putRequestInSpringContext();
99     }
100
101     public static void putRequestInSpringContext() {
102         RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(
103             (HttpServletRequest) promiseRequestIdFilter.wrapIfNeeded(new MockHttpServletRequest())));
104     }
105
106 //    @DataProvider
107 //    public Object[][] msoMethods() {
108 //        return Stream.<ThrowingConsumer<RestMsoImplementation>>of(
109 //
110 //                client -> client.Get(new Object(), "/any path", new RestObject<>(), false),
111 //                client -> client.GetForObject("/any path", Object.class),
112 //                client -> client.Post("", "some payload", "/any path", new RestObject<>()),
113 //                client -> client.PostForObject("some payload", "/any path", Object.class),
114 //                client -> client.Put(Object.class, new RequestDetailsWrapper(), "/any path", new RestObject<>())
115 //
116 //        ).map(l -> ImmutableList.of(l).toArray()).collect(Collectors.toList()).toArray(new Object[][]{});
117 //    }
118 //
119 //    @Test(dataProvider = "msoMethods")
120 //    public void mso(Consumer<RestMsoImplementation> f) throws Exception {
121 //        final TestUtils.JavaxRsClientMocks mocks = setAndGetMocksInsideRestImpl(restMsoImplementation);
122 //
123 //        f.accept(restMsoImplementation);
124 //
125 //        Invocation.Builder fakeBuilder = mocks.getFakeBuilder();
126 //        Object requestIdValue = verifyXEcompRequestIdHeaderWasAdded(fakeBuilder);
127 //        assertEquals(requestIdValue, captureHeaderKeyAndReturnItsValue(fakeBuilder, "X-ONAP-RequestID"));
128 //
129 //        assertThat((String) captureHeaderKeyAndReturnItsValue(fakeBuilder, "Authorization"), startsWith("Basic "));
130 //        assertThat(captureHeaderKeyAndReturnItsValue(fakeBuilder, "X-ONAP-PartnerName"), equalTo("VID"));
131 //    }
132 //
133 //    @Test
134 //    public void whenProvideMsoRestCallUserId_builderHasXRequestorIDHeader() throws Exception {
135 //
136 //        final TestUtils.JavaxRsClientMocks mocks = setAndGetMocksInsideRestImpl(restMsoImplementation);
137 //        String randomUserName = randomAlphabetic(10);
138 //
139 //        restMsoImplementation.restCall(HttpMethod.DELETE, String.class, null, "abc", Optional.of(randomUserName));
140 //        assertEquals(randomUserName, captureHeaderKeyAndReturnItsValue(mocks.getFakeBuilder(), "X-RequestorID"));
141 //    }
142
143     @DataProvider
144     public Object[][] aaiMethods() {
145         return Stream.<ThrowingConsumer<AAIRestInterface>>of(
146
147                 client -> client.RestGet("from app id", "some transId", Unchecked.toURI("/any path"), false),
148                 client -> client.Delete("whatever source id", "some transId", "/any path"),
149                 client -> client.RestPost("from app id", "/any path", "some payload", false),
150                 client -> client.RestPut("from app id", "/any path", "some payload", false, false)
151
152         ).map(l -> ImmutableList.of(l).toArray()).collect(Collectors.toList()).toArray(new Object[][]{});
153     }
154
155     @Test(dataProvider = "aaiMethods")
156     public void aai(Consumer<AAIRestInterface> f) throws Exception {
157         final TestUtils.JavaxRsClientMocks mocks = setAndGetMocksInsideRestImpl(aaiRestInterface);
158
159         f.accept(aaiRestInterface);
160
161         verifyXEcompRequestIdHeaderWasAdded(mocks.getFakeBuilder());
162     }
163
164 //    @Test(dataProvider = "schedulerMethods")
165 //    public void scheduler(Consumer<AAIRestInterface> f) throws Exception {
166 //
167 //        This test os not feasible in the wat acheduler is implemented today,
168 //        as Scheduler's client is rewritten in every call.
169 //
170 //        :-(
171 //
172 //    }
173
174     private Object verifyXEcompRequestIdHeaderWasAdded(Invocation.Builder fakeBuilder) {
175         final String requestIdHeader = "x-ecomp-requestid";
176         final String uuidRegex = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}";
177         Object requestId = captureHeaderKeyAndReturnItsValue(fakeBuilder, requestIdHeader);
178
179         assertThat("header '" + requestIdHeader + "' should be a uuid", requestId,
180                 allOf(instanceOf(String.class), hasToString(matchesPattern(uuidRegex))));
181         return requestId;
182     }
183
184     private Object captureHeaderKeyAndReturnItsValue(Invocation.Builder fakeBuilder, String headerName) {
185         // Checks that the builder was called with either one of header("x-ecomp-requestid", uuid)
186         // or the plural brother: headers(Map.of("x-ecomp-requestid", Set.of(uuid))
187
188         Object requestId;
189         // The 'verify()' will capture the request id. If no match -- AssertionError will
190         // catch for a second chance -- another 'verify()'.
191         try {
192             ArgumentCaptor<Object> argumentCaptor = ArgumentCaptor.forClass(Object.class);
193             Mockito.verify(fakeBuilder)
194                     .header(
195                             Matchers.argThat(s -> equalsIgnoreCase(s, headerName)),
196                             argumentCaptor.capture()
197                     );
198             requestId = argumentCaptor.getValue();
199
200         } catch (AssertionError e) {
201             Mockito.verify(fakeBuilder).headers(multivaluedMapArgumentCaptor.capture());
202
203             final MultivaluedMap<String, Object> headersMap = multivaluedMapArgumentCaptor.getValue();
204             final String thisRequestIdHeader = getFromSetCaseInsensitive(headersMap.keySet(), headerName);
205
206             assertThat(headersMap.keySet(), hasItem(thisRequestIdHeader));
207             requestId = headersMap.getFirst(thisRequestIdHeader);
208         }
209         return requestId;
210     }
211
212     private String getFromSetCaseInsensitive(Set<String> set, String key) {
213         return set.stream()
214                 .filter(anotherString -> anotherString.equalsIgnoreCase(key))
215                 .findFirst()
216                 .orElse(key);
217     }
218
219     private TestUtils.JavaxRsClientMocks setAndGetMocksInsideRestImpl(Class<?> clazz) throws IllegalAccessException {
220         TestUtils.JavaxRsClientMocks mocks = new TestUtils.JavaxRsClientMocks();
221         Client fakeClient = mocks.getFakeClient();
222
223         FieldUtils.writeStaticField(clazz, "client", fakeClient, true);
224
225         return mocks;
226     }
227
228     private TestUtils.JavaxRsClientMocks setAndGetMocksInsideRestImpl(Object instance) throws IllegalAccessException {
229         TestUtils.JavaxRsClientMocks mocks = new TestUtils.JavaxRsClientMocks();
230         Client fakeClient = mocks.getFakeClient();
231
232         FieldUtils.writeField(instance, "client", fakeClient, true);
233
234         return mocks;
235     }
236
237     @FunctionalInterface
238     public interface ThrowingConsumer<T> extends Consumer<T> {
239         @Override
240         default void accept(T t) {
241             try {
242                 acceptThrows(t);
243             } catch (Exception e) {
244                 throw new RuntimeException(e);
245             }
246         }
247
248         void acceptThrows(T t) throws Exception;
249     }
250
251 }