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.core.MediaType;
28 import javax.ws.rs.core.Response;
29 import javax.ws.rs.core.Response.Status;
31 import org.junit.Before;
32 import org.junit.Test;
33 import org.mockito.ArgumentCaptor;
34 import org.mockito.Mockito;
35 import org.onap.aai.restclient.client.OperationResult;
36 import org.onap.aai.restclient.client.RestClient;
37 import org.onap.aai.restclient.enums.RestAuthenticationMode;
38 import org.onap.aai.restclient.rest.RestClientBuilder;
40 import com.sun.jersey.api.client.Client;
41 import com.sun.jersey.api.client.ClientResponse;
42 import com.sun.jersey.api.client.UniformInterfaceException;
43 import com.sun.jersey.api.client.WebResource;
44 import com.sun.jersey.api.client.WebResource.Builder;
45 import com.sun.jersey.core.util.MultivaluedMapImpl;
47 public class RestfulClientTest {
49 private static final String TEST_URL = "http://localhost:9000/aai/v7";
51 private final MultivaluedMapImpl emptyMap = new MultivaluedMapImpl();
53 private RestClientBuilder mockClientBuilder;
54 private Client mockedClient;
55 private WebResource mockedWebResource;
56 private Builder mockedBuilder;
57 private ClientResponse mockedClientResponse;
60 * Test case initialization
62 * @throws Exception the exception
64 @SuppressWarnings("unchecked")
66 public void init() throws Exception {
67 mockedClientResponse = Mockito.mock(ClientResponse.class);
68 setResponseStatus(Response.Status.OK);
69 Mockito.when(mockedClientResponse.getHeaders()).thenReturn(emptyMap);
70 Mockito.when(mockedClientResponse.getEntity(String.class)).thenReturn("hello");
72 mockedBuilder = Mockito.mock(Builder.class);
73 Mockito.when(mockedBuilder.get(Mockito.any(Class.class))).thenReturn(mockedClientResponse);
74 Mockito.when(mockedBuilder.post(Mockito.any(Class.class))).thenReturn(mockedClientResponse);
75 Mockito.when(mockedBuilder.put(Mockito.any(Class.class))).thenReturn(mockedClientResponse);
76 Mockito.when(mockedBuilder.delete(Mockito.any(Class.class))).thenReturn(mockedClientResponse);
77 Mockito.when(mockedBuilder.head()).thenReturn(mockedClientResponse);
79 mockedWebResource = Mockito.mock(WebResource.class);
80 Mockito.when(mockedWebResource.accept(Mockito.<MediaType>anyVararg())).thenReturn(mockedBuilder);
82 mockedClient = Mockito.mock(Client.class);
83 Mockito.when(mockedClient.resource(Mockito.anyString())).thenReturn(mockedWebResource);
85 mockClientBuilder = Mockito.mock(RestClientBuilder.class);
86 Mockito.when(mockClientBuilder.getClient()).thenReturn(mockedClient);
90 public void validateConstructors() {
91 RestClient restClient = new RestClient();
92 assertNotNull(restClient);
93 restClient = new RestClient(mockClientBuilder);
94 assertNotNull(restClient);
98 public void validateBasicClientConstruction() throws Exception {
99 Client client = new RestClient(mockClientBuilder).authenticationMode(RestAuthenticationMode.HTTP_NOAUTH)
100 .connectTimeoutMs(1000).readTimeoutMs(500).getClient();
101 assertNotNull(client);
105 public void validateClientWithSslBasicAuthConstruction() throws Exception {
106 Client client = new RestClient(mockClientBuilder).authenticationMode(RestAuthenticationMode.SSL_BASIC)
107 .connectTimeoutMs(1000).readTimeoutMs(500).basicAuthPassword("password").basicAuthUsername("username")
109 assertNotNull(client);
113 public void validateClientWithSslCertConstruction() throws Exception {
114 // This test covers the standard SSL settings, i.e. no validation
115 assertNotNull(buildClient());
117 RestClient restClient = new RestClient(mockClientBuilder);
119 // Test with validation enabled
120 Client client = restClient.authenticationMode(RestAuthenticationMode.SSL_CERT).connectTimeoutMs(1000)
121 .readTimeoutMs(500).clientCertFile("cert").clientCertPassword("password").validateServerCertChain(true)
122 .validateServerHostname(true).getClient();
123 assertNotNull(client);
125 // Test with a trust store
126 client = restClient.authenticationMode(RestAuthenticationMode.SSL_CERT).connectTimeoutMs(1000)
127 .readTimeoutMs(500).clientCertFile("cert").clientCertPassword("password").trustStore("truststore")
129 assertNotNull(client);
133 public void validateSuccessfulPut() throws Exception {
134 RestClient restClient = buildClient();
136 OperationResult result = restClient.put(TEST_URL, "", emptyMap, MediaType.APPLICATION_JSON_TYPE,
137 MediaType.APPLICATION_JSON_TYPE);
139 assertEquals(Response.Status.OK.getStatusCode(), result.getResultCode());
140 assertNotNull(result.getResult());
141 assertNull(result.getFailureCause());
143 // Repeat the PUT operation, this time with a return code of 204
144 setResponseToNoContent();
145 result = restClient.put(TEST_URL, "", emptyMap, MediaType.APPLICATION_JSON_TYPE,
146 MediaType.APPLICATION_JSON_TYPE);
148 assertEquals(Response.Status.NO_CONTENT.getStatusCode(), result.getResultCode());
149 assertNull(result.getResult());
150 assertNull(result.getFailureCause());
154 public void validateSuccessfulPost() throws Exception {
155 RestClient restClient = buildClient();
157 OperationResult result = restClient.post(TEST_URL, "", emptyMap, MediaType.APPLICATION_JSON_TYPE,
158 MediaType.APPLICATION_JSON_TYPE);
160 assertEquals(Response.Status.OK.getStatusCode(), result.getResultCode());
161 assertNotNull(result.getResult());
162 assertNull(result.getFailureCause());
164 // Repeat the POST operation, this time with a return code of 204
165 setResponseToNoContent();
166 result = restClient.post(TEST_URL, "", emptyMap, MediaType.APPLICATION_JSON_TYPE,
167 MediaType.APPLICATION_JSON_TYPE);
169 assertEquals(Response.Status.NO_CONTENT.getStatusCode(), result.getResultCode());
170 assertNull(result.getResult());
171 assertNull(result.getFailureCause());
175 public void validateSuccessfulPost_withMultivaluedHeader() throws Exception {
176 RestClient restClient = buildClient();
178 MultivaluedMapImpl headerMap = new MultivaluedMapImpl();
180 headerMap.add("txnId", "123");
181 headerMap.add("txnId", "456");
182 headerMap.add("txnId", "789");
184 OperationResult result = restClient.post(TEST_URL, "", headerMap, MediaType.APPLICATION_JSON_TYPE,
185 MediaType.APPLICATION_JSON_TYPE);
187 // capture the txnId header from the outgoing request
188 ArgumentCaptor<String> txnIdHeaderName = ArgumentCaptor.forClass(String.class);
189 ArgumentCaptor<String> txnIdHeaderValue = ArgumentCaptor.forClass(String.class);
191 Mockito.verify(mockedBuilder, Mockito.atLeast(1)).header(txnIdHeaderName.capture(), txnIdHeaderValue.capture());
192 assertEquals("123;456;789", txnIdHeaderValue.getValue());
194 assertEquals(Response.Status.OK.getStatusCode(), result.getResultCode());
195 assertNotNull(result.getResult());
196 assertNull(result.getFailureCause());
200 public void validateSuccessfulGet() throws Exception {
201 OperationResult result = buildClient().get(TEST_URL, emptyMap, MediaType.APPLICATION_JSON_TYPE);
203 assertEquals(Response.Status.OK.getStatusCode(), result.getResultCode());
204 assertNotNull(result.getResult());
205 assertNull(result.getFailureCause());
209 public void validateSuccessfulGetWithBasicAuth() throws Exception {
210 RestClient restClient = new RestClient(mockClientBuilder).authenticationMode(RestAuthenticationMode.SSL_BASIC)
211 .connectTimeoutMs(1000).readTimeoutMs(500).basicAuthUsername("username").basicAuthUsername("password");
213 OperationResult result = restClient.get(TEST_URL, emptyMap, MediaType.APPLICATION_JSON_TYPE);
215 assertEquals(Response.Status.OK.getStatusCode(), result.getResultCode());
216 assertNotNull(result.getResult());
217 assertNull(result.getFailureCause());
221 public void validateResourceNotFoundGet() throws Exception {
222 setResponseStatus(Response.Status.NOT_FOUND);
223 Mockito.when(mockedClientResponse.getEntity(String.class)).thenReturn("RNF");
225 OperationResult result = buildClient().get(TEST_URL, emptyMap, MediaType.APPLICATION_JSON_TYPE);
227 assertEquals(Response.Status.NOT_FOUND.getStatusCode(), result.getResultCode());
228 assertNull(result.getResult());
229 assertNotNull(result.getFailureCause());
233 public void validateHealthCheck() throws Exception {
234 boolean targetServiceHealthy =
235 buildClient().healthCheck("http://localhost:9000/aai/util/echo", "startSerice", "targetService");
237 assertEquals(true, targetServiceHealthy);
241 public void validateHealthCheckFailureWith403() throws Exception {
242 Mockito.when(mockedClientResponse.getStatus()).thenReturn(Response.Status.FORBIDDEN.getStatusCode());
244 boolean targetServiceHealthy =
245 buildClient().healthCheck("http://localhost:9000/aai/util/echo", "startSerice", "targetService");
247 assertEquals(false, targetServiceHealthy);
251 public void validateHealthCheckFailureWithThrownException() throws Exception {
252 Mockito.when(mockedBuilder.get(Mockito.any(Class.class))).thenThrow(new IllegalArgumentException("error"));
254 boolean targetServiceHealthy =
255 buildClient().healthCheck("http://localhost:9000/aai/util/echo", "startSerice", "targetService");
257 assertEquals(false, targetServiceHealthy);
261 public void validateSuccessfulGetWithRetries() throws Exception {
262 Mockito.when(mockedClientResponse.getStatus()).thenReturn(408).thenReturn(Response.Status.OK.getStatusCode());
263 Mockito.when(mockedClientResponse.getEntity(String.class)).thenReturn("error").thenReturn("ok");
265 OperationResult result = buildClient().get(TEST_URL, emptyMap, MediaType.APPLICATION_JSON_TYPE, 3);
267 assertEquals(Response.Status.OK.getStatusCode(), result.getResultCode());
268 assertNotNull(result.getResult());
269 assertNull(result.getFailureCause());
274 public void validateFailedGetWithRetriesCausedByResourceNotFound() throws Exception {
275 setResponseStatus(Response.Status.NOT_FOUND);
276 Mockito.when(mockedClientResponse.getEntity(String.class)).thenReturn("error").thenReturn("ok");
278 OperationResult result = buildClient().get(TEST_URL, emptyMap, MediaType.APPLICATION_JSON_TYPE, 3);
280 assertEquals(Response.Status.NOT_FOUND.getStatusCode(), result.getResultCode());
281 assertNull(result.getResult());
282 assertNotNull(result.getFailureCause());
287 public void validateFailedGetAfterMaxRetries() throws Exception {
288 setResponseStatus(Response.Status.INTERNAL_SERVER_ERROR);
289 Mockito.when(mockedClientResponse.getEntity(String.class)).thenReturn("error");
291 OperationResult result = buildClient().get(TEST_URL, emptyMap, MediaType.APPLICATION_JSON_TYPE, 3);
293 assertEquals(504, result.getResultCode());
294 assertNull(result.getResult());
295 assertNotNull(result.getFailureCause());
300 public void validateSuccessfulDelete() throws Exception {
301 RestClient restClient = buildClient();
303 OperationResult result = restClient.delete(TEST_URL, emptyMap, MediaType.APPLICATION_JSON_TYPE);
305 assertEquals(Response.Status.OK.getStatusCode(), result.getResultCode());
306 assertNotNull(result.getResult());
307 assertNull(result.getFailureCause());
309 // Repeat the DELETE operation, this time with a return code of 204
310 setResponseToNoContent();
311 result = restClient.delete(TEST_URL, emptyMap, MediaType.APPLICATION_JSON_TYPE);
313 assertEquals(Response.Status.NO_CONTENT.getStatusCode(), result.getResultCode());
314 assertNull(result.getResult());
315 assertNull(result.getFailureCause());
320 public void validateSuccessfulHead() throws Exception {
321 OperationResult result = buildClient().head(TEST_URL, emptyMap, MediaType.APPLICATION_JSON_TYPE);
323 assertEquals(Response.Status.OK.getStatusCode(), result.getResultCode());
324 assertNotNull(result.getResult());
325 assertNull(result.getFailureCause());
330 public void validateSuccessfulPatch() throws Exception {
331 Mockito.when(mockedBuilder.header("X-HTTP-Method-Override", "PATCH")).thenReturn(mockedBuilder);
332 OperationResult result = buildClient().patch(TEST_URL, "", emptyMap, MediaType.APPLICATION_JSON_TYPE,
333 MediaType.APPLICATION_JSON_TYPE);
335 assertEquals(Response.Status.OK.getStatusCode(), result.getResultCode());
336 assertNotNull(result.getResult());
337 assertNull(result.getFailureCause());
342 public void testGetClient() throws Exception {
343 RestClientBuilder restClientBuilder= new RestClientBuilder();
344 restClientBuilder.setAuthenticationMode(RestAuthenticationMode.SSL_BASIC);
345 assertTrue(restClientBuilder.getClient() instanceof Client);
349 * Specify the status code of the response object returned by the mocked client
351 * @param status object storing the status code to mock in the ClientResponse
353 private void setResponseStatus(Status status) {
354 Mockito.when(mockedClientResponse.getStatus()).thenReturn(status.getStatusCode());
358 * Set the mocked client to return a response of "204 No Content"
360 private void setResponseToNoContent() {
361 setResponseStatus(Response.Status.NO_CONTENT);
362 // The Jersey client throws an exception when getEntity() is called following a 204 response
363 UniformInterfaceException uniformInterfaceException = new UniformInterfaceException(mockedClientResponse);
364 Mockito.when(mockedClientResponse.getEntity(String.class)).thenThrow(uniformInterfaceException);
368 * @return a mocked Rest Client object using standard SSL settings
370 private RestClient buildClient() {
371 return new RestClient(mockClientBuilder).authenticationMode(RestAuthenticationMode.SSL_CERT)
372 .connectTimeoutMs(1000).readTimeoutMs(500).clientCertFile("cert").clientCertPassword("password");