blob: 5c42a31dc576daeb760d70a476a4972728060219 [file] [log] [blame]
Aharoni, Pavel (pa0916)ca3cb012018-10-22 15:29:57 +03001/*-
2 * ============LICENSE_START=======================================================
3 * OSAM
4 * ================================================================================
5 * Copyright (C) 2018 AT&T
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
22
23package org.onap.osam.mso.rest;
24
25import com.google.common.collect.ImmutableList;
26import org.apache.commons.lang3.reflect.FieldUtils;
27import org.mockito.ArgumentCaptor;
28import org.mockito.Captor;
29import org.mockito.InjectMocks;
30import org.mockito.Matchers;
31import org.mockito.Mockito;
32import org.mockito.MockitoAnnotations;
33import org.onap.osam.aai.util.AAIRestInterface;
34import org.onap.osam.filters.PromiseEcompRequestIdFilter;
35import org.onap.osam.mso.RestMsoImplementation;
36import org.onap.osam.mso.RestObject;
37import org.onap.osam.testUtils.TestUtils;
38import org.springframework.mock.web.MockHttpServletRequest;
39import org.springframework.web.context.request.RequestContextHolder;
40import org.springframework.web.context.request.ServletRequestAttributes;
41import org.testng.annotations.BeforeClass;
42import org.testng.annotations.BeforeMethod;
43import org.testng.annotations.DataProvider;
44import org.testng.annotations.Test;
45
46import javax.servlet.http.HttpServletRequest;
47import javax.ws.rs.client.Client;
48import javax.ws.rs.client.Invocation;
49import javax.ws.rs.core.MultivaluedMap;
50import java.util.Set;
51import java.util.function.Consumer;
52import java.util.stream.Collectors;
53import java.util.stream.Stream;
54
55import static org.hamcrest.MatcherAssert.assertThat;
56import static org.hamcrest.Matchers.allOf;
57import static org.hamcrest.Matchers.equalToIgnoringCase;
58import static org.hamcrest.Matchers.hasItem;
59import static org.hamcrest.Matchers.hasToString;
60import static org.hamcrest.Matchers.instanceOf;
61import static org.hamcrest.Matchers.matchesPattern;
62
63
64public class OutgoingRequestIdTest {
65
66
67 @InjectMocks
68 private RestMsoImplementation restMsoImplementation;
69
70 @InjectMocks
71 private AAIRestInterface aaiRestInterface;
72
73
74 @Captor
75 private ArgumentCaptor<MultivaluedMap<String, Object>> multivaluedMapArgumentCaptor;
76
77 @BeforeClass
78 public void initMocks() {
79 MockitoAnnotations.initMocks(this);
80 }
81
82 @BeforeMethod
83 private void putRequestInSpringContext() {
84 RequestContextHolder.setRequestAttributes(new ServletRequestAttributes((HttpServletRequest) PromiseEcompRequestIdFilter.wrapIfNeeded(new MockHttpServletRequest())));
85 }
86
87 @DataProvider
88 public Object[][] msoMethods() {
89 return Stream.<ThrowingConsumer<RestMsoImplementation>>of(
90
91 client -> client.Get(new Object(), "whatever source id", "/any path", new RestObject<>()),
92 client -> client.GetForObject("whatever source id", "/any path", Object.class),
93 client -> client.Post(new Object(), "some payload", "whatever source id", "/any path", new RestObject<>()),
94 client -> client.PostForObject("some payload", "whatever source id", "/any path", Object.class),
95 client -> client.Put(Object.class, new RequestDetailsWrapper(), "whatever source id", "/any path", new RestObject<>())
96
97 ).map(l -> ImmutableList.of(l).toArray()).collect(Collectors.toList()).toArray(new Object[][]{});
98 }
99
100 @Test(dataProvider = "msoMethods")
101 public void mso(Consumer<RestMsoImplementation> f) throws Exception {
102 final TestUtils.JavaxRsClientMocks mocks = setAndGetMocksInsideRestImpl(restMsoImplementation);
103
104 f.accept(restMsoImplementation);
105
106 verifyRequestIdHeaderWasAdded(mocks.getFakeBuilder());
107 }
108
109 @DataProvider
110 public Object[][] aaiMethods() {
111 return Stream.<ThrowingConsumer<AAIRestInterface>>of(
112
113 client -> client.RestGet("from app id", "some transId", "/any path", false),
114 client -> client.Delete("whatever source id", "some transId", "/any path"),
115 client -> client.RestPost("from app id", "/any path", "some payload", false),
116 client -> client.RestPut("from app id", "/any path", "some payload", false)
117
118 ).map(l -> ImmutableList.of(l).toArray()).collect(Collectors.toList()).toArray(new Object[][]{});
119 }
120
121 //@Test(dataProvider = "aaiMethods")
122 public void aai(Consumer<AAIRestInterface> f) throws Exception {
123 final TestUtils.JavaxRsClientMocks mocks = setAndGetMocksInsideRestImpl(aaiRestInterface);
124
125 f.accept(aaiRestInterface);
126
127 verifyRequestIdHeaderWasAdded(mocks.getFakeBuilder());
128 }
129
130// @Test(dataProvider = "schedulerMethods")
131// public void scheduler(Consumer<AAIRestInterface> f) throws Exception {
132//
133// This test os not feasible in the wat acheduler is implemented today,
134// as Scheduler's client is rewritten in every call.
135//
136// :-(
137//
138// }
139
140 private void verifyRequestIdHeaderWasAdded(Invocation.Builder fakeBuilder) {
141 final String requestIdHeader = "x-ecomp-requestid";
142 final String uuidRegex = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}";
143
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(equalToIgnoringCase(requestIdHeader)),
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(), requestIdHeader);
164
165 assertThat(headersMap.keySet(), hasItem(thisRequestIdHeader));
166 requestId = headersMap.getFirst(thisRequestIdHeader);
167 }
168
169 assertThat("header '" + requestIdHeader + "' should be a uuid", requestId,
170 allOf(instanceOf(String.class), hasToString(matchesPattern(uuidRegex))));
171 }
172
173 private String getFromSetCaseInsensitive(Set<String> set, String key) {
174 return set.stream()
175 .filter(anotherString -> anotherString.equalsIgnoreCase(key))
176 .findFirst()
177 .orElse(key);
178 }
179
180 private TestUtils.JavaxRsClientMocks setAndGetMocksInsideRestImpl(Class<?> clazz) throws IllegalAccessException {
181 TestUtils.JavaxRsClientMocks mocks = new TestUtils.JavaxRsClientMocks();
182 Client fakeClient = mocks.getFakeClient();
183
184 FieldUtils.writeStaticField(clazz, "client", fakeClient, true);
185
186 return mocks;
187 }
188
189 private TestUtils.JavaxRsClientMocks setAndGetMocksInsideRestImpl(Object instance) throws IllegalAccessException {
190 TestUtils.JavaxRsClientMocks mocks = new TestUtils.JavaxRsClientMocks();
191 Client fakeClient = mocks.getFakeClient();
192
193 FieldUtils.writeField(instance, "client", fakeClient, true);
194
195 return mocks;
196 }
197
198 @FunctionalInterface
199 public interface ThrowingConsumer<T> extends Consumer<T> {
200 @Override
201 default void accept(T t) {
202 try {
203 acceptThrows(t);
204 } catch (Exception e) {
205 throw new RuntimeException(e);
206 }
207 }
208
209 void acceptThrows(T t) throws Exception;
210 }
211
212}