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