Fix incorrect result for a server response of 204
[aai/rest-client.git] / src / test / java / org / openecomp / restclient / client / RestfulClientTest.java
1 /*
2  * ============LICENSE_START===========================================================================================
3  * Copyright (c) 2017 AT&T Intellectual Property.
4  * Copyright (c) 2017 Amdocs 
5  * All rights reserved.
6  * =====================================================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
8  * the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
13  * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
14  * specific language governing permissions and limitations under the License.
15  * ============LICENSE_END================================================== ===========================================
16  * 
17  * ECOMP and OpenECOMP are trademarks and service marks of AT&T Intellectual Property.
18  */
19 package org.openecomp.restclient.client;
20
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.assertNotNull;
23 import static org.junit.Assert.assertNull;
24
25 import javax.ws.rs.core.MediaType;
26 import javax.ws.rs.core.Response;
27 import javax.ws.rs.core.Response.Status;
28
29 import org.junit.Before;
30 import org.junit.Test;
31 import org.mockito.Mockito;
32 import org.openecomp.restclient.enums.RestAuthenticationMode;
33 import org.openecomp.restclient.rest.RestClientBuilder;
34
35 import com.sun.jersey.api.client.Client;
36 import com.sun.jersey.api.client.ClientResponse;
37 import com.sun.jersey.api.client.UniformInterfaceException;
38 import com.sun.jersey.api.client.WebResource;
39 import com.sun.jersey.api.client.WebResource.Builder;
40 import com.sun.jersey.core.util.MultivaluedMapImpl;
41
42 public class RestfulClientTest {
43
44     private static final String TEST_URL = "http://localhost:9000/aai/v7";
45
46     private final MultivaluedMapImpl emptyMap = new MultivaluedMapImpl();
47
48     private RestClientBuilder mockClientBuilder;
49     private Client mockedClient;
50     private WebResource mockedWebResource;
51     private Builder mockedBuilder;
52     private ClientResponse mockedClientResponse;
53
54     /**
55      * Test case initialization
56      * 
57      * @throws Exception the exception
58      */
59     @SuppressWarnings("unchecked")
60     @Before
61     public void init() throws Exception {
62         mockedClientResponse = Mockito.mock(ClientResponse.class);
63         setResponseStatus(Response.Status.OK);
64         Mockito.when(mockedClientResponse.getHeaders()).thenReturn(emptyMap);
65         Mockito.when(mockedClientResponse.getEntity(String.class)).thenReturn("hello");
66
67         mockedBuilder = Mockito.mock(Builder.class);
68         Mockito.when(mockedBuilder.get(Mockito.any(Class.class))).thenReturn(mockedClientResponse);
69         Mockito.when(mockedBuilder.post(Mockito.any(Class.class))).thenReturn(mockedClientResponse);
70         Mockito.when(mockedBuilder.put(Mockito.any(Class.class))).thenReturn(mockedClientResponse);
71         Mockito.when(mockedBuilder.delete(Mockito.any(Class.class))).thenReturn(mockedClientResponse);
72         Mockito.when(mockedBuilder.head()).thenReturn(mockedClientResponse);
73
74         mockedWebResource = Mockito.mock(WebResource.class);
75         Mockito.when(mockedWebResource.accept(Mockito.<MediaType>anyVararg())).thenReturn(mockedBuilder);
76
77         mockedClient = Mockito.mock(Client.class);
78         Mockito.when(mockedClient.resource(Mockito.anyString())).thenReturn(mockedWebResource);
79
80         mockClientBuilder = Mockito.mock(RestClientBuilder.class);
81         Mockito.when(mockClientBuilder.getClient()).thenReturn(mockedClient);
82     }
83
84     @Test
85     public void validateConstructors() {
86         RestClient restClient = new RestClient();
87         assertNotNull(restClient);
88         restClient = new RestClient(mockClientBuilder);
89         assertNotNull(restClient);
90     }
91
92     @Test
93     public void validateBasicClientConstruction() throws Exception {
94         Client client = new RestClient(mockClientBuilder).authenticationMode(RestAuthenticationMode.HTTP_NOAUTH)
95                 .connectTimeoutMs(1000).readTimeoutMs(500).getClient();
96         assertNotNull(client);
97     }
98
99     @Test
100     public void validateClientWithSslBasicAuthConstruction() throws Exception {
101         Client client = new RestClient(mockClientBuilder).authenticationMode(RestAuthenticationMode.SSL_BASIC)
102                 .connectTimeoutMs(1000).readTimeoutMs(500).basicAuthPassword("password").basicAuthUsername("username")
103                 .getClient();
104         assertNotNull(client);
105     }
106
107     @Test
108     public void validateClientWithSslCertConstruction() throws Exception {
109         // This test covers the standard SSL settings, i.e. no validation
110         assertNotNull(buildClient());
111
112         RestClient restClient = new RestClient(mockClientBuilder);
113
114         // Test with validation enabled
115         Client client = restClient.authenticationMode(RestAuthenticationMode.SSL_CERT).connectTimeoutMs(1000)
116                 .readTimeoutMs(500).clientCertFile("cert").clientCertPassword("password").validateServerCertChain(true)
117                 .validateServerHostname(true).getClient();
118         assertNotNull(client);
119
120         // Test with a trust store
121         client = restClient.authenticationMode(RestAuthenticationMode.SSL_CERT).connectTimeoutMs(1000)
122                 .readTimeoutMs(500).clientCertFile("cert").clientCertPassword("password").trustStore("truststore")
123                 .getClient();
124         assertNotNull(client);
125     }
126
127     @Test
128     public void validateSuccessfulPut() throws Exception {
129         RestClient restClient = buildClient();
130
131         OperationResult result = restClient.put(TEST_URL, "", emptyMap, MediaType.APPLICATION_JSON_TYPE,
132                 MediaType.APPLICATION_JSON_TYPE);
133
134         assertEquals(Response.Status.OK.getStatusCode(), result.getResultCode());
135         assertNotNull(result.getResult());
136         assertNull(result.getFailureCause());
137
138         // Repeat the PUT operation, this time with a return code of 204
139         setResponseToNoContent();
140         result = restClient.put(TEST_URL, "", emptyMap, MediaType.APPLICATION_JSON_TYPE,
141                 MediaType.APPLICATION_JSON_TYPE);
142
143         assertEquals(Response.Status.NO_CONTENT.getStatusCode(), result.getResultCode());
144         assertNull(result.getResult());
145         assertNull(result.getFailureCause());
146     }
147
148     @Test
149     public void validateSuccessfulPost() throws Exception {
150         RestClient restClient = buildClient();
151
152         OperationResult result = restClient.post(TEST_URL, "", emptyMap, MediaType.APPLICATION_JSON_TYPE,
153                 MediaType.APPLICATION_JSON_TYPE);
154
155         assertEquals(Response.Status.OK.getStatusCode(), result.getResultCode());
156         assertNotNull(result.getResult());
157         assertNull(result.getFailureCause());
158
159         // Repeat the POST operation, this time with a return code of 204
160         setResponseToNoContent();
161         result = restClient.post(TEST_URL, "", emptyMap, MediaType.APPLICATION_JSON_TYPE,
162                 MediaType.APPLICATION_JSON_TYPE);
163
164         assertEquals(Response.Status.NO_CONTENT.getStatusCode(), result.getResultCode());
165         assertNull(result.getResult());
166         assertNull(result.getFailureCause());
167     }
168
169     @Test
170     public void validateSuccessfulGet() throws Exception {
171         OperationResult result = buildClient().get(TEST_URL, emptyMap, MediaType.APPLICATION_JSON_TYPE);
172
173         assertEquals(Response.Status.OK.getStatusCode(), result.getResultCode());
174         assertNotNull(result.getResult());
175         assertNull(result.getFailureCause());
176     }
177
178     @Test
179     public void validateSuccessfulGetWithBasicAuth() throws Exception {
180         RestClient restClient = new RestClient(mockClientBuilder).authenticationMode(RestAuthenticationMode.SSL_BASIC)
181                 .connectTimeoutMs(1000).readTimeoutMs(500).basicAuthUsername("username").basicAuthUsername("password");
182
183         OperationResult result = restClient.get(TEST_URL, emptyMap, MediaType.APPLICATION_JSON_TYPE);
184
185         assertEquals(Response.Status.OK.getStatusCode(), result.getResultCode());
186         assertNotNull(result.getResult());
187         assertNull(result.getFailureCause());
188     }
189
190     @Test
191     public void validateResourceNotFoundGet() throws Exception {
192         setResponseStatus(Response.Status.NOT_FOUND);
193         Mockito.when(mockedClientResponse.getEntity(String.class)).thenReturn("RNF");
194
195         OperationResult result = buildClient().get(TEST_URL, emptyMap, MediaType.APPLICATION_JSON_TYPE);
196
197         assertEquals(Response.Status.NOT_FOUND.getStatusCode(), result.getResultCode());
198         assertNull(result.getResult());
199         assertNotNull(result.getFailureCause());
200     }
201
202     @Test
203     public void validateHealthCheck() throws Exception {
204         boolean targetServiceHealthy =
205                 buildClient().healthCheck("http://localhost:9000/aai/util/echo", "startSerice", "targetService");
206
207         assertEquals(true, targetServiceHealthy);
208     }
209
210     @Test
211     public void validateHealthCheckFailureWith403() throws Exception {
212         Mockito.when(mockedClientResponse.getStatus()).thenReturn(Response.Status.FORBIDDEN.getStatusCode());
213
214         boolean targetServiceHealthy =
215                 buildClient().healthCheck("http://localhost:9000/aai/util/echo", "startSerice", "targetService");
216
217         assertEquals(false, targetServiceHealthy);
218     }
219
220     @Test
221     public void validateHealthCheckFailureWithThrownException() throws Exception {
222         Mockito.when(mockedBuilder.get(Mockito.any(Class.class))).thenThrow(new IllegalArgumentException("error"));
223
224         boolean targetServiceHealthy =
225                 buildClient().healthCheck("http://localhost:9000/aai/util/echo", "startSerice", "targetService");
226
227         assertEquals(false, targetServiceHealthy);
228     }
229
230     @Test
231     public void validateSuccessfulGetWithRetries() throws Exception {
232         Mockito.when(mockedClientResponse.getStatus()).thenReturn(408).thenReturn(Response.Status.OK.getStatusCode());
233         Mockito.when(mockedClientResponse.getEntity(String.class)).thenReturn("error").thenReturn("ok");
234
235         OperationResult result = buildClient().get(TEST_URL, emptyMap, MediaType.APPLICATION_JSON_TYPE, 3);
236
237         assertEquals(Response.Status.OK.getStatusCode(), result.getResultCode());
238         assertNotNull(result.getResult());
239         assertNull(result.getFailureCause());
240
241     }
242
243     @Test
244     public void validateFailedGetWithRetriesCausedByResourceNotFound() throws Exception {
245         setResponseStatus(Response.Status.NOT_FOUND);
246         Mockito.when(mockedClientResponse.getEntity(String.class)).thenReturn("error").thenReturn("ok");
247
248         OperationResult result = buildClient().get(TEST_URL, emptyMap, MediaType.APPLICATION_JSON_TYPE, 3);
249
250         assertEquals(Response.Status.NOT_FOUND.getStatusCode(), result.getResultCode());
251         assertNull(result.getResult());
252         assertNotNull(result.getFailureCause());
253
254     }
255
256     @Test
257     public void validateFailedGetAfterMaxRetries() throws Exception {
258         setResponseStatus(Response.Status.INTERNAL_SERVER_ERROR);
259         Mockito.when(mockedClientResponse.getEntity(String.class)).thenReturn("error");
260
261         OperationResult result = buildClient().get(TEST_URL, emptyMap, MediaType.APPLICATION_JSON_TYPE, 3);
262
263         assertEquals(504, result.getResultCode());
264         assertNull(result.getResult());
265         assertNotNull(result.getFailureCause());
266
267     }
268
269     @Test
270     public void validateSuccessfulDelete() throws Exception {
271         RestClient restClient = buildClient();
272
273         OperationResult result = restClient.delete(TEST_URL, emptyMap, MediaType.APPLICATION_JSON_TYPE);
274
275         assertEquals(Response.Status.OK.getStatusCode(), result.getResultCode());
276         assertNotNull(result.getResult());
277         assertNull(result.getFailureCause());
278
279         // Repeat the DELETE operation, this time with a return code of 204
280         setResponseToNoContent();
281         result = restClient.delete(TEST_URL, emptyMap, MediaType.APPLICATION_JSON_TYPE);
282
283         assertEquals(Response.Status.NO_CONTENT.getStatusCode(), result.getResultCode());
284         assertNull(result.getResult());
285         assertNull(result.getFailureCause());
286     }
287
288
289     @Test
290     public void validateSuccessfulHead() throws Exception {
291         OperationResult result = buildClient().head(TEST_URL, emptyMap, MediaType.APPLICATION_JSON_TYPE);
292
293         assertEquals(Response.Status.OK.getStatusCode(), result.getResultCode());
294         assertNotNull(result.getResult());
295         assertNull(result.getFailureCause());
296
297     }
298
299     @Test
300     public void validateSuccessfulPatch() throws Exception {
301         Mockito.when(mockedBuilder.header("X-HTTP-Method-Override", "PATCH")).thenReturn(mockedBuilder);
302         OperationResult result = buildClient().patch(TEST_URL, "", emptyMap, MediaType.APPLICATION_JSON_TYPE,
303                 MediaType.APPLICATION_JSON_TYPE);
304
305         assertEquals(Response.Status.OK.getStatusCode(), result.getResultCode());
306         assertNotNull(result.getResult());
307         assertNull(result.getFailureCause());
308
309     }
310
311     /**
312      * Specify the status code of the response object returned by the mocked client
313      * 
314      * @param status object storing the status code to mock in the ClientResponse
315      */
316     private void setResponseStatus(Status status) {
317         Mockito.when(mockedClientResponse.getStatus()).thenReturn(status.getStatusCode());
318     }
319
320     /**
321      * Set the mocked client to return a response of "204 No Content"
322      */
323     private void setResponseToNoContent() {
324         setResponseStatus(Response.Status.NO_CONTENT);
325         // The Jersey client throws an exception when getEntity() is called following a 204 response
326         UniformInterfaceException uniformInterfaceException = new UniformInterfaceException(mockedClientResponse);
327         Mockito.when(mockedClientResponse.getEntity(String.class)).thenThrow(uniformInterfaceException);
328     }
329
330     /**
331      * @return a mocked Rest Client object using standard SSL settings
332      */
333     private RestClient buildClient() {
334         return new RestClient(mockClientBuilder).authenticationMode(RestAuthenticationMode.SSL_CERT)
335                 .connectTimeoutMs(1000).readTimeoutMs(500).clientCertFile("cert").clientCertPassword("password");
336     }
337
338 }