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.Invocation.Builder;
30 import javax.ws.rs.client.WebTarget;
31 import javax.ws.rs.core.MediaType;
32 import javax.ws.rs.core.MultivaluedHashMap;
33 import javax.ws.rs.core.MultivaluedMap;
34 import javax.ws.rs.core.Response;
35 import javax.ws.rs.core.Response.Status;
36 import org.junit.Before;
37 import org.junit.Test;
38 import org.mockito.ArgumentCaptor;
39 import org.mockito.Mockito;
40 import org.onap.aai.restclient.enums.RestAuthenticationMode;
41 import org.onap.aai.restclient.rest.RestClientBuilder;
43 public class RestfulClientTest {
45 private static final String TEST_URL = "http://localhost:9000/aai/v7";
47 private final MultivaluedMap<String, String> emptyMap = new MultivaluedHashMap<>();
49 private RestClientBuilder mockClientBuilder;
50 private Client mockedClient;
51 private WebTarget mockedWebTarget;
52 private Builder mockedBuilder;
53 private Response mockedClientResponse;
56 * Test case initialization
58 * @throws Exception the exception
61 public void init() throws Exception {
62 mockedClientResponse = Mockito.mock(Response.class);
63 setResponseStatus(Response.Status.OK);
64 Mockito.when(mockedClientResponse.getHeaders()).thenReturn(new MultivaluedHashMap<>());
65 Mockito.when(mockedClientResponse.readEntity(String.class)).thenReturn("hello");
67 mockedBuilder = Mockito.mock(Builder.class);
68 Mockito.when(mockedBuilder.get()).thenReturn(mockedClientResponse);
69 Mockito.when(mockedBuilder.post(Mockito.any())).thenReturn(mockedClientResponse);
70 Mockito.when(mockedBuilder.put(Mockito.any())).thenReturn(mockedClientResponse);
71 Mockito.when(mockedBuilder.delete()).thenReturn(mockedClientResponse);
72 Mockito.when(mockedBuilder.head()).thenReturn(mockedClientResponse);
73 Mockito.when(mockedBuilder.accept(Mockito.any(MediaType.class))).thenReturn(mockedBuilder);
75 mockedWebTarget = Mockito.mock(WebTarget.class);
76 Mockito.when(mockedWebTarget.request()).thenReturn(mockedBuilder);
78 mockedClient = Mockito.mock(Client.class);
79 Mockito.when(mockedClient.target(Mockito.anyString())).thenReturn(mockedWebTarget);
81 mockClientBuilder = Mockito.mock(RestClientBuilder.class);
82 Mockito.when(mockClientBuilder.getClient()).thenReturn(mockedClient);
86 public void validateConstructors() {
87 RestClient restClient = new RestClient();
88 assertNotNull(restClient);
89 restClient = new RestClient(mockClientBuilder);
90 assertNotNull(restClient);
94 public void validateBasicClientConstruction() throws Exception {
95 Client client = new RestClient(mockClientBuilder).authenticationMode(RestAuthenticationMode.HTTP_NOAUTH)
96 .connectTimeoutMs(1000).readTimeoutMs(500).getClient();
97 assertNotNull(client);
101 public void validateClientWithSslBasicAuthConstruction() throws Exception {
102 Client client = new RestClient(mockClientBuilder).authenticationMode(RestAuthenticationMode.SSL_BASIC)
103 .connectTimeoutMs(1000).readTimeoutMs(500).basicAuthPassword("password").basicAuthUsername("username")
105 assertNotNull(client);
109 public void validateClientWithSslCertConstruction() throws Exception {
110 // This test covers the standard SSL settings, i.e. no validation
111 assertNotNull(buildClient());
113 RestClient restClient = new RestClient(mockClientBuilder);
115 // Test with validation enabled
116 Client client = restClient.authenticationMode(RestAuthenticationMode.SSL_CERT).connectTimeoutMs(1000)
117 .readTimeoutMs(500).clientCertFile("cert").clientCertPassword("password").validateServerCertChain(true)
118 .validateServerHostname(true).getClient();
119 assertNotNull(client);
121 // Test with a trust store
122 client = restClient.authenticationMode(RestAuthenticationMode.SSL_CERT).connectTimeoutMs(1000)
123 .readTimeoutMs(500).clientCertFile("cert").clientCertPassword("password").trustStore("truststore")
125 assertNotNull(client);
129 public void validateSuccessfulPut() throws Exception {
130 RestClient restClient = buildClient();
132 OperationResult result = restClient.put(TEST_URL, "", emptyMap, MediaType.APPLICATION_JSON_TYPE,
133 MediaType.APPLICATION_JSON_TYPE);
135 assertEquals(Response.Status.OK.getStatusCode(), result.getResultCode());
136 assertNotNull(result.getResult());
137 assertNull(result.getFailureCause());
139 // Repeat the PUT operation, this time with a return code of 204
140 setResponseToNoContent();
141 result = restClient.put(TEST_URL, "", emptyMap, MediaType.APPLICATION_JSON_TYPE,
142 MediaType.APPLICATION_JSON_TYPE);
144 assertEquals(Response.Status.NO_CONTENT.getStatusCode(), result.getResultCode());
145 assertNull(result.getResult());
146 assertNull(result.getFailureCause());
150 public void validateSuccessfulPost() throws Exception {
151 RestClient restClient = buildClient();
153 OperationResult result = restClient.post(TEST_URL, "", emptyMap, MediaType.APPLICATION_JSON_TYPE,
154 MediaType.APPLICATION_JSON_TYPE);
156 assertEquals(Response.Status.OK.getStatusCode(), result.getResultCode());
157 assertNotNull(result.getResult());
158 assertNull(result.getFailureCause());
160 // Repeat the POST operation, this time with a return code of 204
161 setResponseToNoContent();
162 result = restClient.post(TEST_URL, "", emptyMap, MediaType.APPLICATION_JSON_TYPE,
163 MediaType.APPLICATION_JSON_TYPE);
165 assertEquals(Response.Status.NO_CONTENT.getStatusCode(), result.getResultCode());
166 assertNull(result.getResult());
167 assertNull(result.getFailureCause());
171 public void validateSuccessfulPost_withMultivaluedHeader() throws Exception {
172 RestClient restClient = buildClient();
174 MultivaluedMap<String, String> headerMap = new MultivaluedHashMap<>();
176 headerMap.add("txnId", "123");
177 headerMap.add("txnId", "456");
178 headerMap.add("txnId", "789");
180 OperationResult result = restClient.post(TEST_URL, "", headerMap, MediaType.APPLICATION_JSON_TYPE,
181 MediaType.APPLICATION_JSON_TYPE);
183 // capture the txnId header from the outgoing request
184 ArgumentCaptor<String> txnIdHeaderName = ArgumentCaptor.forClass(String.class);
185 ArgumentCaptor<String> txnIdHeaderValue = ArgumentCaptor.forClass(String.class);
187 Mockito.verify(mockedBuilder, Mockito.atLeast(1)).header(txnIdHeaderName.capture(), txnIdHeaderValue.capture());
188 assertEquals("123;456;789", txnIdHeaderValue.getValue());
190 assertEquals(Response.Status.OK.getStatusCode(), result.getResultCode());
191 assertNotNull(result.getResult());
192 assertNull(result.getFailureCause());
196 public void validateSuccessfulGet() throws Exception {
197 OperationResult result = buildClient().get(TEST_URL, emptyMap, MediaType.APPLICATION_JSON_TYPE);
199 assertEquals(Response.Status.OK.getStatusCode(), result.getResultCode());
200 assertNotNull(result.getResult());
201 assertNull(result.getFailureCause());
205 public void validateSuccessfulGetWithBasicAuth() throws Exception {
206 RestClient restClient = new RestClient(mockClientBuilder).authenticationMode(RestAuthenticationMode.SSL_BASIC)
207 .connectTimeoutMs(1000).readTimeoutMs(500).basicAuthUsername("username").basicAuthUsername("password");
209 OperationResult result = restClient.get(TEST_URL, emptyMap, MediaType.APPLICATION_JSON_TYPE);
211 assertEquals(Response.Status.OK.getStatusCode(), result.getResultCode());
212 assertNotNull(result.getResult());
213 assertNull(result.getFailureCause());
217 public void validateResourceNotFoundGet() throws Exception {
218 setResponseStatus(Response.Status.NOT_FOUND);
219 Mockito.when(mockedClientResponse.readEntity(String.class)).thenReturn("RNF");
221 OperationResult result = buildClient().get(TEST_URL, emptyMap, MediaType.APPLICATION_JSON_TYPE);
223 assertEquals(Response.Status.NOT_FOUND.getStatusCode(), result.getResultCode());
224 assertNull(result.getResult());
225 assertNotNull(result.getFailureCause());
229 public void validateHealthCheck() throws Exception {
230 boolean targetServiceHealthy =
231 buildClient().healthCheck("http://localhost:9000/aai/util/echo", "startSerice", "targetService");
233 assertEquals(true, targetServiceHealthy);
237 public void validateHealthCheckFailureWith403() throws Exception {
238 Mockito.when(mockedClientResponse.getStatus()).thenReturn(Response.Status.FORBIDDEN.getStatusCode());
240 boolean targetServiceHealthy =
241 buildClient().healthCheck("http://localhost:9000/aai/util/echo", "startSerice", "targetService");
243 assertEquals(false, targetServiceHealthy);
247 public void validateHealthCheckFailureWithThrownException() throws Exception {
248 Mockito.when(mockedBuilder.get()).thenThrow(new IllegalArgumentException("error"));
250 boolean targetServiceHealthy =
251 buildClient().healthCheck("http://localhost:9000/aai/util/echo", "startSerice", "targetService");
253 assertEquals(false, targetServiceHealthy);
257 public void validateSuccessfulGetWithRetries() throws Exception {
258 Mockito.when(mockedClientResponse.getStatus()).thenReturn(408).thenReturn(Response.Status.OK.getStatusCode());
259 Mockito.when(mockedClientResponse.readEntity(String.class)).thenReturn("error").thenReturn("ok");
261 OperationResult result = buildClient().get(TEST_URL, emptyMap, MediaType.APPLICATION_JSON_TYPE, 3);
263 assertEquals(Response.Status.OK.getStatusCode(), result.getResultCode());
264 assertNotNull(result.getResult());
265 assertNull(result.getFailureCause());
270 public void validateFailedGetWithRetriesCausedByResourceNotFound() throws Exception {
271 setResponseStatus(Response.Status.NOT_FOUND);
272 Mockito.when(mockedClientResponse.readEntity(String.class)).thenReturn("error").thenReturn("ok");
274 OperationResult result = buildClient().get(TEST_URL, emptyMap, MediaType.APPLICATION_JSON_TYPE, 3);
276 assertEquals(Response.Status.NOT_FOUND.getStatusCode(), result.getResultCode());
277 assertNull(result.getResult());
278 assertNotNull(result.getFailureCause());
283 public void validateFailedGetAfterMaxRetries() throws Exception {
284 setResponseStatus(Response.Status.INTERNAL_SERVER_ERROR);
285 Mockito.when(mockedClientResponse.readEntity(String.class)).thenReturn("error");
287 OperationResult result = buildClient().get(TEST_URL, emptyMap, MediaType.APPLICATION_JSON_TYPE, 3);
289 assertEquals(504, result.getResultCode());
290 assertNull(result.getResult());
291 assertNotNull(result.getFailureCause());
296 public void validateSuccessfulDelete() throws Exception {
297 RestClient restClient = buildClient();
299 OperationResult result = restClient.delete(TEST_URL, emptyMap, MediaType.APPLICATION_JSON_TYPE);
301 assertEquals(Response.Status.OK.getStatusCode(), result.getResultCode());
302 assertNotNull(result.getResult());
303 assertNull(result.getFailureCause());
305 // Repeat the DELETE operation, this time with a return code of 204
306 setResponseToNoContent();
307 result = restClient.delete(TEST_URL, emptyMap, MediaType.APPLICATION_JSON_TYPE);
309 assertEquals(Response.Status.NO_CONTENT.getStatusCode(), result.getResultCode());
310 assertNull(result.getResult());
311 assertNull(result.getFailureCause());
315 public void validateSuccessfulHead() throws Exception {
316 OperationResult result = buildClient().head(TEST_URL, emptyMap, MediaType.APPLICATION_JSON_TYPE);
318 assertEquals(Response.Status.OK.getStatusCode(), result.getResultCode());
319 assertNotNull(result.getResult());
320 assertNull(result.getFailureCause());
324 public void validateSuccessfulPatch() throws Exception {
325 Mockito.when(mockedBuilder.header("X-HTTP-Method-Override", "PATCH")).thenReturn(mockedBuilder);
326 OperationResult result = buildClient().patch(TEST_URL, "", emptyMap, MediaType.APPLICATION_JSON_TYPE,
327 MediaType.APPLICATION_JSON_TYPE);
329 assertEquals(Response.Status.OK.getStatusCode(), result.getResultCode());
330 assertNotNull(result.getResult());
331 assertNull(result.getFailureCause());
335 public void testGetClient() throws Exception {
336 RestClientBuilder restClientBuilder = new RestClientBuilder();
337 restClientBuilder.setAuthenticationMode(RestAuthenticationMode.SSL_BASIC);
338 restClientBuilder.setTruststoreFilename("truststore");
339 assertTrue(restClientBuilder.getClient() instanceof Client);
343 * Specify the status code of the response object returned by the mocked client
345 * @param status object storing the status code to mock in the ClientResponse
347 private void setResponseStatus(Status status) {
348 Mockito.when(mockedClientResponse.getStatus()).thenReturn(status.getStatusCode());
352 * Set the mocked client to return a response of "204 No Content"
354 private void setResponseToNoContent() {
355 setResponseStatus(Response.Status.NO_CONTENT);
356 // The Jersey client throws an exception when readEntity() is called following a 204 response
357 ProcessingException processingException = new ProcessingException("No content");
358 Mockito.when(mockedClientResponse.readEntity(String.class)).thenThrow(processingException);
362 * @return a mocked Rest Client object using standard SSL settings
364 private RestClient buildClient() {
365 return new RestClient(mockClientBuilder).authenticationMode(RestAuthenticationMode.SSL_CERT)
366 .connectTimeoutMs(1000).readTimeoutMs(500).clientCertFile("cert").clientCertPassword("password");