2 * ============LICENSE_START===========================================================================================
3 * Copyright (c) 2017 AT&T Intellectual Property.
4 * Copyright (c) 2017 Amdocs
5 * Modification Copyright (c) 2018 IBM.
7 * =====================================================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
14 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
15 * specific language governing permissions and limitations under the License.
16 * ============LICENSE_END================================================== ===========================================
18 * ECOMP and OpenECOMP are trademarks and service marks of AT&T Intellectual Property.
20 package org.onap.aai.restclient.client;
22 import static org.junit.Assert.assertEquals;
23 import static org.junit.Assert.assertNotNull;
24 import static org.junit.Assert.assertNull;
25 import static org.junit.Assert.assertTrue;
27 import javax.ws.rs.ProcessingException;
28 import javax.ws.rs.client.Client;
29 import javax.ws.rs.client.ClientBuilder;
30 import javax.ws.rs.client.Invocation.Builder;
31 import javax.ws.rs.client.WebTarget;
32 import javax.ws.rs.core.MediaType;
33 import javax.ws.rs.core.MultivaluedHashMap;
34 import javax.ws.rs.core.MultivaluedMap;
35 import javax.ws.rs.core.Response;
36 import javax.ws.rs.core.Response.Status;
37 import org.junit.Before;
38 import org.junit.Test;
39 import org.mockito.ArgumentCaptor;
40 import org.mockito.Mockito;
41 import org.onap.aai.restclient.enums.RestAuthenticationMode;
42 import org.onap.aai.restclient.rest.RestClientBuilder;
44 public class RestfulClientTest {
46 private static final String TEST_URL = "http://localhost:9000/aai/v7";
48 private final MultivaluedMap<String, String> emptyMap = new MultivaluedHashMap<>();
49 private final ClientBuilder clientBuilder = ClientBuilder.newBuilder();
51 private RestClientBuilder mockClientBuilder;
52 private Client mockedClient;
53 private WebTarget mockedWebTarget;
54 private Builder mockedBuilder;
55 private Response mockedClientResponse;
58 * Test case initialization
60 * @throws Exception the exception
63 public void init() throws Exception {
64 mockedClientResponse = Mockito.mock(Response.class);
65 setResponseStatus(Response.Status.OK);
66 Mockito.when(mockedClientResponse.getHeaders()).thenReturn(new MultivaluedHashMap<>());
67 Mockito.when(mockedClientResponse.readEntity(String.class)).thenReturn("hello");
69 mockedBuilder = Mockito.mock(Builder.class);
70 Mockito.when(mockedBuilder.get()).thenReturn(mockedClientResponse);
71 Mockito.when(mockedBuilder.post(Mockito.any())).thenReturn(mockedClientResponse);
72 Mockito.when(mockedBuilder.put(Mockito.any())).thenReturn(mockedClientResponse);
73 Mockito.when(mockedBuilder.delete()).thenReturn(mockedClientResponse);
74 Mockito.when(mockedBuilder.head()).thenReturn(mockedClientResponse);
75 Mockito.when(mockedBuilder.accept(Mockito.any(MediaType.class))).thenReturn(mockedBuilder);
77 mockedWebTarget = Mockito.mock(WebTarget.class);
78 Mockito.when(mockedWebTarget.request()).thenReturn(mockedBuilder);
80 mockedClient = Mockito.mock(Client.class);
81 Mockito.when(mockedClient.target(Mockito.anyString())).thenReturn(mockedWebTarget);
83 mockClientBuilder = Mockito.mock(RestClientBuilder.class);
84 Mockito.when(mockClientBuilder.getClient()).thenReturn(mockedClient);
88 public void validateConstructors() {
89 RestClient restClient = new RestClient(clientBuilder);
90 assertNotNull(restClient);
91 restClient = new RestClient(mockClientBuilder);
92 assertNotNull(restClient);
96 public void validateBasicClientConstruction() throws Exception {
97 Client client = new RestClient(mockClientBuilder).authenticationMode(RestAuthenticationMode.HTTP_NOAUTH)
98 .connectTimeoutMs(1000).readTimeoutMs(500).getClient();
99 assertNotNull(client);
103 public void validateClientWithSslBasicAuthConstruction() throws Exception {
104 Client client = new RestClient(mockClientBuilder).authenticationMode(RestAuthenticationMode.SSL_BASIC)
105 .connectTimeoutMs(1000).readTimeoutMs(500).basicAuthPassword("password").basicAuthUsername("username")
107 assertNotNull(client);
111 public void validateClientWithSslCertConstruction() throws Exception {
112 // This test covers the standard SSL settings, i.e. no validation
113 assertNotNull(buildClient());
115 RestClient restClient = new RestClient(mockClientBuilder);
117 // Test with validation enabled
118 Client client = restClient.authenticationMode(RestAuthenticationMode.SSL_CERT).connectTimeoutMs(1000)
119 .readTimeoutMs(500).clientCertFile("cert").clientCertPassword("password").validateServerCertChain(true)
120 .validateServerHostname(true).getClient();
121 assertNotNull(client);
123 // Test with a trust store
124 client = restClient.authenticationMode(RestAuthenticationMode.SSL_CERT).connectTimeoutMs(1000)
125 .readTimeoutMs(500).clientCertFile("cert").clientCertPassword("password").trustStore("truststore")
127 assertNotNull(client);
131 public void validateSuccessfulPut() throws Exception {
132 RestClient restClient = buildClient();
134 OperationResult result = restClient.put(TEST_URL, "", emptyMap, MediaType.APPLICATION_JSON_TYPE,
135 MediaType.APPLICATION_JSON_TYPE);
137 assertEquals(Response.Status.OK.getStatusCode(), result.getResultCode());
138 assertNotNull(result.getResult());
139 assertNull(result.getFailureCause());
141 // Repeat the PUT operation, this time with a return code of 204
142 setResponseToNoContent();
143 result = restClient.put(TEST_URL, "", emptyMap, MediaType.APPLICATION_JSON_TYPE,
144 MediaType.APPLICATION_JSON_TYPE);
146 assertEquals(Response.Status.NO_CONTENT.getStatusCode(), result.getResultCode());
147 assertNull(result.getResult());
148 assertNull(result.getFailureCause());
152 public void validateSuccessfulPost() throws Exception {
153 RestClient restClient = buildClient();
155 OperationResult result = restClient.post(TEST_URL, "", emptyMap, MediaType.APPLICATION_JSON_TYPE,
156 MediaType.APPLICATION_JSON_TYPE);
158 assertEquals(Response.Status.OK.getStatusCode(), result.getResultCode());
159 assertNotNull(result.getResult());
160 assertNull(result.getFailureCause());
162 // Repeat the POST operation, this time with a return code of 204
163 setResponseToNoContent();
164 result = restClient.post(TEST_URL, "", emptyMap, MediaType.APPLICATION_JSON_TYPE,
165 MediaType.APPLICATION_JSON_TYPE);
167 assertEquals(Response.Status.NO_CONTENT.getStatusCode(), result.getResultCode());
168 assertNull(result.getResult());
169 assertNull(result.getFailureCause());
173 public void validateSuccessfulPost_withMultivaluedHeader() throws Exception {
174 RestClient restClient = buildClient();
176 MultivaluedMap<String, String> headerMap = new MultivaluedHashMap<>();
178 headerMap.add("txnId", "123");
179 headerMap.add("txnId", "456");
180 headerMap.add("txnId", "789");
182 OperationResult result = restClient.post(TEST_URL, "", headerMap, MediaType.APPLICATION_JSON_TYPE,
183 MediaType.APPLICATION_JSON_TYPE);
185 // capture the txnId header from the outgoing request
186 ArgumentCaptor<String> txnIdHeaderName = ArgumentCaptor.forClass(String.class);
187 ArgumentCaptor<String> txnIdHeaderValue = ArgumentCaptor.forClass(String.class);
189 Mockito.verify(mockedBuilder, Mockito.atLeast(1)).header(txnIdHeaderName.capture(), txnIdHeaderValue.capture());
190 assertEquals("123;456;789", txnIdHeaderValue.getValue());
192 assertEquals(Response.Status.OK.getStatusCode(), result.getResultCode());
193 assertNotNull(result.getResult());
194 assertNull(result.getFailureCause());
198 public void validateSuccessfulGet() throws Exception {
199 OperationResult result = buildClient().get(TEST_URL, emptyMap, MediaType.APPLICATION_JSON_TYPE);
201 assertEquals(Response.Status.OK.getStatusCode(), result.getResultCode());
202 assertNotNull(result.getResult());
203 assertNull(result.getFailureCause());
207 public void validateSuccessfulGetWithBasicAuth() throws Exception {
208 RestClient restClient = new RestClient(mockClientBuilder).authenticationMode(RestAuthenticationMode.SSL_BASIC)
209 .connectTimeoutMs(1000).readTimeoutMs(500).basicAuthUsername("username").basicAuthUsername("password");
211 OperationResult result = restClient.get(TEST_URL, emptyMap, MediaType.APPLICATION_JSON_TYPE);
213 assertEquals(Response.Status.OK.getStatusCode(), result.getResultCode());
214 assertNotNull(result.getResult());
215 assertNull(result.getFailureCause());
219 public void validateResourceNotFoundGet() throws Exception {
220 setResponseStatus(Response.Status.NOT_FOUND);
221 Mockito.when(mockedClientResponse.readEntity(String.class)).thenReturn("RNF");
223 OperationResult result = buildClient().get(TEST_URL, emptyMap, MediaType.APPLICATION_JSON_TYPE);
225 assertEquals(Response.Status.NOT_FOUND.getStatusCode(), result.getResultCode());
226 assertNull(result.getResult());
227 assertNotNull(result.getFailureCause());
231 public void validateHealthCheck() throws Exception {
232 boolean targetServiceHealthy =
233 buildClient().healthCheck("http://localhost:9000/aai/util/echo", "startSerice", "targetService");
235 assertEquals(true, targetServiceHealthy);
239 public void validateHealthCheckFailureWith403() throws Exception {
240 Mockito.when(mockedClientResponse.getStatus()).thenReturn(Response.Status.FORBIDDEN.getStatusCode());
242 boolean targetServiceHealthy =
243 buildClient().healthCheck("http://localhost:9000/aai/util/echo", "startSerice", "targetService");
245 assertEquals(false, targetServiceHealthy);
249 public void validateHealthCheckFailureWithThrownException() throws Exception {
250 Mockito.when(mockedBuilder.get()).thenThrow(new IllegalArgumentException("error"));
252 boolean targetServiceHealthy =
253 buildClient().healthCheck("http://localhost:9000/aai/util/echo", "startSerice", "targetService");
255 assertEquals(false, targetServiceHealthy);
259 public void validateSuccessfulGetWithRetries() throws Exception {
260 Mockito.when(mockedClientResponse.getStatus()).thenReturn(408).thenReturn(Response.Status.OK.getStatusCode());
261 Mockito.when(mockedClientResponse.readEntity(String.class)).thenReturn("error").thenReturn("ok");
263 OperationResult result = buildClient().get(TEST_URL, emptyMap, MediaType.APPLICATION_JSON_TYPE, 3);
265 assertEquals(Response.Status.OK.getStatusCode(), result.getResultCode());
266 assertNotNull(result.getResult());
267 assertNull(result.getFailureCause());
272 public void validateFailedGetWithRetriesCausedByResourceNotFound() throws Exception {
273 setResponseStatus(Response.Status.NOT_FOUND);
274 Mockito.when(mockedClientResponse.readEntity(String.class)).thenReturn("error").thenReturn("ok");
276 OperationResult result = buildClient().get(TEST_URL, emptyMap, MediaType.APPLICATION_JSON_TYPE, 3);
278 assertEquals(Response.Status.NOT_FOUND.getStatusCode(), result.getResultCode());
279 assertNull(result.getResult());
280 assertNotNull(result.getFailureCause());
285 public void validateFailedGetAfterMaxRetries() throws Exception {
286 setResponseStatus(Response.Status.INTERNAL_SERVER_ERROR);
287 Mockito.when(mockedClientResponse.readEntity(String.class)).thenReturn("error");
289 OperationResult result = buildClient().get(TEST_URL, emptyMap, MediaType.APPLICATION_JSON_TYPE, 3);
291 assertEquals(504, result.getResultCode());
292 assertNull(result.getResult());
293 assertNotNull(result.getFailureCause());
298 public void validateSuccessfulDelete() throws Exception {
299 RestClient restClient = buildClient();
301 OperationResult result = restClient.delete(TEST_URL, emptyMap, MediaType.APPLICATION_JSON_TYPE);
303 assertEquals(Response.Status.OK.getStatusCode(), result.getResultCode());
304 assertNotNull(result.getResult());
305 assertNull(result.getFailureCause());
307 // Repeat the DELETE operation, this time with a return code of 204
308 setResponseToNoContent();
309 result = restClient.delete(TEST_URL, emptyMap, MediaType.APPLICATION_JSON_TYPE);
311 assertEquals(Response.Status.NO_CONTENT.getStatusCode(), result.getResultCode());
312 assertNull(result.getResult());
313 assertNull(result.getFailureCause());
317 public void validateSuccessfulHead() throws Exception {
318 OperationResult result = buildClient().head(TEST_URL, emptyMap, MediaType.APPLICATION_JSON_TYPE);
320 assertEquals(Response.Status.OK.getStatusCode(), result.getResultCode());
321 assertNotNull(result.getResult());
322 assertNull(result.getFailureCause());
326 public void validateSuccessfulPatch() throws Exception {
327 Mockito.when(mockedBuilder.header("X-HTTP-Method-Override", "PATCH")).thenReturn(mockedBuilder);
328 OperationResult result = buildClient().patch(TEST_URL, "", emptyMap, MediaType.APPLICATION_JSON_TYPE,
329 MediaType.APPLICATION_JSON_TYPE);
331 assertEquals(Response.Status.OK.getStatusCode(), result.getResultCode());
332 assertNotNull(result.getResult());
333 assertNull(result.getFailureCause());
337 public void testGetClient() throws Exception {
338 RestClientBuilder restClientBuilder = new RestClientBuilder(clientBuilder);
339 restClientBuilder.setAuthenticationMode(RestAuthenticationMode.SSL_BASIC);
340 restClientBuilder.setTruststoreFilename("truststore");
341 assertTrue(restClientBuilder.getClient() instanceof Client);
345 * Specify the status code of the response object returned by the mocked client
347 * @param status object storing the status code to mock in the ClientResponse
349 private void setResponseStatus(Status status) {
350 Mockito.when(mockedClientResponse.getStatus()).thenReturn(status.getStatusCode());
354 * Set the mocked client to return a response of "204 No Content"
356 private void setResponseToNoContent() {
357 setResponseStatus(Response.Status.NO_CONTENT);
358 // The Jersey client throws an exception when readEntity() is called following a 204 response
359 ProcessingException processingException = new ProcessingException("No content");
360 Mockito.when(mockedClientResponse.readEntity(String.class)).thenThrow(processingException);
364 * @return a mocked Rest Client object using standard SSL settings
366 private RestClient buildClient() {
367 return new RestClient(mockClientBuilder).authenticationMode(RestAuthenticationMode.SSL_CERT)
368 .connectTimeoutMs(1000).readTimeoutMs(500).clientCertFile("cert").clientCertPassword("password");