1 package org.openecomp.restclient.client;
\r
3 import org.junit.Before;
\r
4 import org.junit.Test;
\r
5 import org.openecomp.restclient.client.OperationResult;
\r
6 import org.openecomp.restclient.client.RestClient;
\r
7 import org.openecomp.restclient.rest.RestClientBuilder;
\r
9 import static org.junit.Assert.assertTrue;
\r
10 import static org.junit.Assert.assertNull;
\r
11 import static org.junit.Assert.assertEquals;
\r
13 import javax.ws.rs.GET;
\r
14 import javax.ws.rs.Path;
\r
15 import javax.ws.rs.core.MediaType;
\r
17 import com.sun.jersey.test.framework.AppDescriptor;
\r
18 import com.sun.jersey.test.framework.JerseyTest;
\r
19 import com.sun.jersey.test.framework.WebAppDescriptor;
\r
21 import com.sun.jersey.api.client.Client;
\r
25 * This suite of tests is intended to exercise the behaviour of the {@link RestClient}.
\r
27 public class RESTClientTest extends JerseyTest {
\r
29 private static final String GOOD_AAI_ENDPOINT = "testaai/good";
\r
30 private static final String FAIL_ALWAYS_AAI_ENDPOINT = "testaai/failalways";
\r
31 private static final String FAIL_THEN_SUCCEED_ENDPOINT = "testaai/failthensucceed";
\r
32 private static final String INVALID_AAI_ENDPOINT = "testaai/bad";
\r
34 private static final String AAI_GET_REPLY_PAYLOAD = "Reply from AAI";
\r
36 private static final int SUCCESS_RESULT_CODE = 200;
\r
37 private static final int INVALID_END_POINT_RESULT_CODE = 404;
\r
38 private static final int INTERNAL_ERR_RESULT_CODE = 500;
\r
39 private static final int TIMEOUT_RESULT_CODE = 504;
\r
43 * Creates a new instance of the {@link RESTClientTest} test suite.
\r
45 public RESTClientTest() throws Exception {
\r
47 // Tell our in memory container to look here for resource endpoints.
\r
48 super("org.openecomp.restclient.client");
\r
53 protected AppDescriptor configure() {
\r
54 return new WebAppDescriptor.Builder().build();
\r
59 * Perform common initialization actions that need to run before every unit test.
\r
62 public void setup() {
\r
64 // Initialize our test endpoints to make sure that all of their
\r
65 // counters have valid starting values
\r
66 AAI_FailAlways_Stub.initialize();
\r
67 AAI_FailThenSucceed_Stub.initialize();
\r
72 * This test validates that all of the {@link RestClient}'s configurable parameters can be set via
\r
73 * its fluent interface and that those values are successfully passed down to the underlying
\r
74 * {@link RestClientBuilder} instance.
\r
77 public void configureAAIClientTest() {
\r
79 final boolean VALIDATE_SERVER = true;
\r
80 final boolean VALIDATE_CERT_CHAIN = true;
\r
81 final String CLIENT_CERT_FILE = "myCertFile";
\r
82 final String CLIENT_CERT_PASSWORD = "My voice is my password";
\r
83 final String TRUST_STORE = "myTrustStore";
\r
84 final int CONNECT_TIMEOUT = 5000;
\r
85 final int READ_TIMEOUT = 5000;
\r
87 // Create an instance of our test version of the REST client builder.
\r
88 TestRestClientBuilder clientBuilder = new TestRestClientBuilder();
\r
90 // Now, create a new instance of the {@link AAIClient} and configure
\r
92 RestClient testClient =
\r
93 new RestClient(clientBuilder).validateServerHostname(true).validateServerCertChain(true)
\r
94 .clientCertFile("myCertFile").clientCertPassword("My voice is my password")
\r
95 .trustStore("myTrustStore").connectTimeoutMs(5000).readTimeoutMs(5000);
\r
97 // Validate that the parameters of the test REST client builder that
\r
98 // we passed to the AAI client have been set according to what we
\r
99 // passed in when we instantiated the AAI client.
\r
100 assertEquals("Unexpected 'validate server host name' value", VALIDATE_SERVER,
\r
101 clientBuilder.isValidateServerHostname());
\r
102 assertEquals("Unexpected 'validate certificat chain' value", VALIDATE_CERT_CHAIN,
\r
103 clientBuilder.isValidateServerCertChain());
\r
104 assertTrue("Unexpected client certificate filename",
\r
105 CLIENT_CERT_FILE.equals(clientBuilder.getClientCertFileName()));
\r
106 assertTrue("Unexpected client certificate password",
\r
107 CLIENT_CERT_PASSWORD.equals(clientBuilder.getClientCertPassword()));
\r
108 assertTrue("Unexpected trust store filename",
\r
109 TRUST_STORE.equals(clientBuilder.getTruststoreFilename()));
\r
110 assertEquals("Unexpected connection timeout value", CONNECT_TIMEOUT,
\r
111 clientBuilder.getConnectTimeoutInMs());
\r
112 assertEquals("Unexpected read timeout value", READ_TIMEOUT, clientBuilder.getReadTimeoutInMs());
\r
117 * This test validates that the {@link RestClient} can submit a GET request to a valid REST
\r
118 * endpoint and receive a valid response.
\r
121 public void queryAAI_SuccessTest() {
\r
123 // Create an instance of the AAIClient that uses our test version of
\r
124 // the REST client builder.
\r
125 RestClient testClient = new RestClient(new TestRestClientBuilder());
\r
127 // Query our stubbed out AAI with a URL that we expecte to get a successful
\r
129 OperationResult or =
\r
130 testClient.get(getBaseURI() + GOOD_AAI_ENDPOINT, null, MediaType.APPLICATION_JSON_TYPE);
\r
132 // Validate that a successful query returns a result code of 200.
\r
133 assertEquals("Unexpected result code", SUCCESS_RESULT_CODE, or.getResultCode());
\r
135 // Validate that no error cause gets set on a successful query.
\r
136 assertNull("Operation result failure code should not be set for successful GET",
\r
137 or.getFailureCause());
\r
139 // Validate that our query returned the expected payload from our dummy
\r
141 assertTrue("Incorrect payload returned from AAI query",
\r
142 AAI_GET_REPLY_PAYLOAD.equals(or.getResult()));
\r
147 * This test validates that the {@link RestClient} behaves as expected when query requests are
\r
150 * Specifically, the following scenarios are covered:<br>
\r
151 * 1) Submitting a GET request to an invalid REST endpoint 2) Submitting a GET request to a valid
\r
152 * endpoint which throws an error rather than replying successfully.
\r
154 * Note that this test exercises the 'single attempt' variant of the query method.
\r
157 public void queryAAI_FailureTest() {
\r
159 // Create an instance of the AAIClient that uses our test version of
\r
160 // the REST client builder.
\r
161 RestClient testClient = new RestClient(new TestRestClientBuilder());
\r
163 // Query our stubbed out AAI with a URL that we expecte to get a successful
\r
165 OperationResult or =
\r
166 testClient.get(getBaseURI() + INVALID_AAI_ENDPOINT, null, MediaType.APPLICATION_JSON_TYPE);
\r
168 // Validate that an attempt to query a non-existing endpoint results in
\r
170 assertEquals("Unexpected result code", INVALID_END_POINT_RESULT_CODE, or.getResultCode());
\r
172 // Validate that no payload was set since the query failed.
\r
173 assertNull("Payload should not be set on 404 error", or.getResult());
\r
175 // Now, submit a query request to the stubbed AAI.
\r
176 or = testClient.get(getBaseURI() + FAIL_ALWAYS_AAI_ENDPOINT, null,
\r
177 MediaType.APPLICATION_JSON_TYPE);
\r
179 // Validate that a query to a avalid returns a result code of 500.
\r
180 assertEquals("Unexpected result code", INTERNAL_ERR_RESULT_CODE, or.getResultCode());
\r
185 * This test validates the behaviour of querying the AAI with a number of retries requested in the
\r
186 * case where we never get a successful reply.
\r
189 public void queryAAIWithRetries_TimeoutTest() {
\r
191 int NUM_RETRIES = 3;
\r
194 // Create an instance of the AAIClient that uses our test version of
\r
195 // the REST client builder.
\r
196 RestClient testClient = new RestClient(new TestRestClientBuilder());
\r
198 // Initialize our test endpoint to make sure that all of its
\r
199 // counters have valid starting values
\r
200 // AAI_FailAlways_Stub.initialize();
\r
202 // Perform a query against the stubbed AAI, specifying a number of times
\r
203 // to retry in the event of an error.
\r
204 OperationResult or = testClient.get(getBaseURI() + FAIL_ALWAYS_AAI_ENDPOINT, null,
\r
205 MediaType.APPLICATION_JSON_TYPE, NUM_RETRIES);
\r
207 // Validate that failing for all of our retry attempts results in a
\r
209 assertEquals("Unexpected result code", TIMEOUT_RESULT_CODE, or.getResultCode());
\r
211 // Validate that our stubbed AAI actually received the expected number
\r
212 // of retried requests.
\r
213 assertEquals("Unexpected number of retries", NUM_RETRIES, AAI_FailAlways_Stub.getCount);
\r
218 * This test validates the behaviour of querying the AAI with a number of retries requested in the
\r
219 * case where our query initially fails but then succeeds on one of the subsequent retries.
\r
222 public void queryAAIWithRetries_FailThenSucceedTest() {
\r
224 int num_retries = AAI_FailThenSucceed_Stub.MAX_FAILURES + 2;
\r
226 // Create an instance of the AAIClient that uses our test version of
\r
227 // the REST client builder.
\r
228 RestClient testClient = new RestClient(new TestRestClientBuilder());
\r
230 // Initialize our test endpoint to make sure that all of its
\r
231 // counters have valid starting values.
\r
232 // AAI_FailThenSucceed_Stub.initialize();
\r
234 // Perform a query against the stubbed AAI, specifying a number of times
\r
235 // to retry in the event of an error.
\r
236 OperationResult or = testClient.get(getBaseURI() + FAIL_THEN_SUCCEED_ENDPOINT, null,
\r
237 MediaType.APPLICATION_JSON_TYPE, num_retries);
\r
239 // Validate that after failing a few attempts we finally got back a
\r
241 assertEquals("Unexpected result code", SUCCESS_RESULT_CODE, or.getResultCode());
\r
243 // Validate that our stubbed AAI actually received the expected number
\r
244 // of retried requests.
\r
245 assertEquals("Unexpected number of retries", AAI_FailThenSucceed_Stub.MAX_FAILURES + 1,
\r
246 AAI_FailThenSucceed_Stub.getCount);
\r
251 * This class provides a simple in-memory REST end point to stand in for a real AAI.
\r
253 * This endpoint always returns a valid reply to a GET request and is used for success path
\r
256 @Path(GOOD_AAI_ENDPOINT)
\r
257 public static class AAI_Success_Stub {
\r
260 * This is the end point for GET requests. It just returns a simple, pre-canned response
\r
263 * @return - A pre-canned response.
\r
266 public String getEndpoint() {
\r
267 return AAI_GET_REPLY_PAYLOAD;
\r
273 * This class provides a simple in-memory REST end point to stand in for a real AAI.
\r
275 * This endpoint always returns throws an error instead of responding successfully and is used for
\r
276 * certain failure path tests.
\r
278 @Path(FAIL_ALWAYS_AAI_ENDPOINT)
\r
279 public static class AAI_FailAlways_Stub {
\r
282 * Maintains a running count of the number of GET requests that have been received.
\r
284 public static int getCount;
\r
288 * Resets all of the endpoints counters.
\r
290 public static void initialize() {
\r
296 * This is the end point for GET requests. It just throws an error instead of returning a valid
\r
299 * @return - NONE. We actually throw an exception intentionally instead of returning.
\r
302 public String getEndpoint() {
\r
304 // Keep track of the number of get requests that we have received
\r
305 // so that this value can be used for validation purposes later.
\r
308 // Always just throw an error instead of replying successfully.
\r
309 throw new UnsupportedOperationException("Intentional Failure");
\r
315 * This class provides a simple in-memory REST end point to stand in for a real AAI.
\r
317 * This end point will throw errors instead of responding for a certain number of requests, after
\r
318 * which it will return a valid, pre-canned response.
\r
320 * @return - A pre-canned response.
\r
322 @Path(FAIL_THEN_SUCCEED_ENDPOINT)
\r
323 public static class AAI_FailThenSucceed_Stub {
\r
326 * The number of requests for which we should throw errors before responding successfully.
\r
328 public static int MAX_FAILURES = 2;
\r
331 * Maintains a running count of the number of GET requests that have been received.
\r
333 public static int getCount;
\r
336 * Maintains a running count of the number of requests which we have failed, so that we will
\r
337 * know when to stop failing and return a valid response.
\r
339 private static int failCount;
\r
343 * Resets all of the endpoints counters.
\r
345 public static void initialize() {
\r
352 * This is the end point for GET requests. It will throw errors for a certain number of requests
\r
353 * and then return a valid response.
\r
355 * @return - A pre-canned response string.
\r
358 public String getEndpoint() {
\r
360 // Keep track of the number of get requests that we have received
\r
361 // so that this value can be used for validation purposes later.
\r
364 // We only want to fail a set number of times, so check now to
\r
365 // see what we should do.
\r
366 if (failCount < MAX_FAILURES) {
\r
368 throw new UnsupportedOperationException("Intentional Failure");
\r
371 // We've failed as often as we need to. Time to reply
\r
374 return AAI_GET_REPLY_PAYLOAD;
\r
381 * This class overrides the behaviour of the {@link RestClientBuilder} used by the
\r
382 * {@link RestClient} to just return the in memory client provided by the JerseyTest framework.
\r
384 private class TestRestClientBuilder extends RestClientBuilder {
\r
387 public Client getClient() throws Exception {
\r