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