Fix for overriding skipTests variable.
[vid.git] / vid-app-common / src / test / java / org / onap / vid / mso / rest / OutgoingRequestIdTest.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.changeManagement.RequestDetailsWrapper;
8 import org.onap.vid.controller.filter.PromiseEcompRequestIdFilter;
9 import org.onap.vid.mso.RestMsoImplementation;
10 import org.onap.vid.mso.RestObject;
11 import org.onap.vid.testUtils.TestUtils;
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.function.Consumer;
26 import java.util.stream.Collectors;
27 import java.util.stream.Stream;
28
29 import static org.apache.commons.lang3.StringUtils.equalsIgnoreCase;
30 import static org.hamcrest.MatcherAssert.assertThat;
31 import static org.hamcrest.Matchers.*;
32
33
34 public class OutgoingRequestIdTest {
35
36
37     @InjectMocks
38     private RestMsoImplementation restMsoImplementation;
39
40     @InjectMocks
41     private AAIRestInterface aaiRestInterface;
42
43
44     @Captor
45     private ArgumentCaptor<MultivaluedMap<String, Object>> multivaluedMapArgumentCaptor;
46
47     @BeforeClass
48     public void initMocks() {
49         MockitoAnnotations.initMocks(this);
50     }
51
52     @BeforeMethod
53     private void putRequestInSpringContext() {
54         RequestContextHolder.setRequestAttributes(new ServletRequestAttributes((HttpServletRequest) PromiseEcompRequestIdFilter.wrapIfNeeded(new MockHttpServletRequest())));
55     }
56
57     @DataProvider
58     public Object[][] msoMethods() {
59         return Stream.<ThrowingConsumer<RestMsoImplementation>>of(
60
61                 client -> client.Get(new Object(), "whatever source id", "/any path", new RestObject<>()),
62                 client -> client.GetForObject("whatever source id", "/any path", Object.class),
63                 client -> client.Post(new Object(), "some payload", "whatever source id", "/any path", new RestObject<>()),
64                 client -> client.PostForObject("some payload", "whatever source id", "/any path", Object.class),
65                 client -> client.Put(Object.class, new RequestDetailsWrapper(), "whatever source id", "/any path", new RestObject<>())
66
67         ).map(l -> ImmutableList.of(l).toArray()).collect(Collectors.toList()).toArray(new Object[][]{});
68     }
69
70     @Test(dataProvider = "msoMethods")
71     public void mso(Consumer<RestMsoImplementation> f) throws Exception {
72         final TestUtils.JavaxRsClientMocks mocks = setAndGetMocksInsideRestImpl(restMsoImplementation);
73
74         f.accept(restMsoImplementation);
75
76         verifyRequestIdHeaderWasAdded(mocks.getFakeBuilder());
77     }
78
79     @DataProvider
80     public Object[][] aaiMethods() {
81         return Stream.<ThrowingConsumer<AAIRestInterface>>of(
82
83                 client -> client.RestGet("from app id", "some transId", "/any path", false),
84                 client -> client.Delete("whatever source id", "some transId", "/any path"),
85                 client -> client.RestPost("from app id", "/any path", "some payload", false),
86                 client -> client.RestPut("from app id", "/any path", "some payload", false)
87
88         ).map(l -> ImmutableList.of(l).toArray()).collect(Collectors.toList()).toArray(new Object[][]{});
89     }
90
91     //@Test(dataProvider = "aaiMethods")
92     public void aai(Consumer<AAIRestInterface> f) throws Exception {
93         final TestUtils.JavaxRsClientMocks mocks = setAndGetMocksInsideRestImpl(aaiRestInterface);
94
95         f.accept(aaiRestInterface);
96
97         verifyRequestIdHeaderWasAdded(mocks.getFakeBuilder());
98     }
99
100 //    @Test(dataProvider = "schedulerMethods")
101 //    public void scheduler(Consumer<AAIRestInterface> f) throws Exception {
102 //
103 //        This test os not feasible in the wat acheduler is implemented today,
104 //        as Scheduler's client is rewritten in every call.
105 //
106 //        :-(
107 //
108 //    }
109
110     private void verifyRequestIdHeaderWasAdded(Invocation.Builder fakeBuilder) {
111         final String requestIdHeader = "x-ecomp-requestid";
112         final String uuidRegex = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}";
113
114         // Checks that the builder was called with either one of header("x-ecomp-requestid", uuid)
115         // or the plural brother: headers(Map.of("x-ecomp-requestid", Set.of(uuid))
116
117         Object requestId;
118         // The 'verify()' will capture the request id. If no match -- AssertionError will
119         // catch for a second chance -- another 'verify()'.
120         try {
121             ArgumentCaptor<Object> argumentCaptor = ArgumentCaptor.forClass(Object.class);
122             Mockito.verify(fakeBuilder)
123                     .header(
124                             Matchers.argThat(s -> equalsIgnoreCase(s, requestIdHeader)),
125                             argumentCaptor.capture()
126                     );
127             requestId = argumentCaptor.getValue();
128
129         } catch (AssertionError e) {
130             Mockito.verify(fakeBuilder).headers(multivaluedMapArgumentCaptor.capture());
131
132             final MultivaluedMap<String, Object> headersMap = multivaluedMapArgumentCaptor.getValue();
133             final String thisRequestIdHeader = getFromSetCaseInsensitive(headersMap.keySet(), requestIdHeader);
134
135             assertThat(headersMap.keySet(), hasItem(thisRequestIdHeader));
136             requestId = headersMap.getFirst(thisRequestIdHeader);
137         }
138
139         assertThat("header '" + requestIdHeader + "' should be a uuid", requestId,
140                 allOf(instanceOf(String.class), hasToString(matchesPattern(uuidRegex))));
141     }
142
143     private String getFromSetCaseInsensitive(Set<String> set, String key) {
144         return set.stream()
145                 .filter(anotherString -> anotherString.equalsIgnoreCase(key))
146                 .findFirst()
147                 .orElse(key);
148     }
149
150     private TestUtils.JavaxRsClientMocks setAndGetMocksInsideRestImpl(Class<?> clazz) throws IllegalAccessException {
151         TestUtils.JavaxRsClientMocks mocks = new TestUtils.JavaxRsClientMocks();
152         Client fakeClient = mocks.getFakeClient();
153
154         FieldUtils.writeStaticField(clazz, "client", fakeClient, true);
155
156         return mocks;
157     }
158
159     private TestUtils.JavaxRsClientMocks setAndGetMocksInsideRestImpl(Object instance) throws IllegalAccessException {
160         TestUtils.JavaxRsClientMocks mocks = new TestUtils.JavaxRsClientMocks();
161         Client fakeClient = mocks.getFakeClient();
162
163         FieldUtils.writeField(instance, "client", fakeClient, true);
164
165         return mocks;
166     }
167
168     @FunctionalInterface
169     public interface ThrowingConsumer<T> extends Consumer<T> {
170         @Override
171         default void accept(T t) {
172             try {
173                 acceptThrows(t);
174             } catch (Exception e) {
175                 throw new RuntimeException(e);
176             }
177         }
178
179         void acceptThrows(T t) throws Exception;
180     }
181
182 }