Initial OpenEcomp A&AI Rest Client commit.
[aai/rest-client.git] / src / test / java / org / openecomp / restclient / client / RESTClientTest.java
diff --git a/src/test/java/org/openecomp/restclient/client/RESTClientTest.java b/src/test/java/org/openecomp/restclient/client/RESTClientTest.java
new file mode 100644 (file)
index 0000000..b049c38
--- /dev/null
@@ -0,0 +1,391 @@
+package org.openecomp.restclient.client;\r
+\r
+import org.junit.Before;\r
+import org.junit.Test;\r
+import org.openecomp.restclient.client.OperationResult;\r
+import org.openecomp.restclient.client.RestClient;\r
+import org.openecomp.restclient.rest.RestClientBuilder;\r
+\r
+import static org.junit.Assert.assertTrue;\r
+import static org.junit.Assert.assertNull;\r
+import static org.junit.Assert.assertEquals;\r
+\r
+import javax.ws.rs.GET;\r
+import javax.ws.rs.Path;\r
+import javax.ws.rs.core.MediaType;\r
+\r
+import com.sun.jersey.test.framework.AppDescriptor;\r
+import com.sun.jersey.test.framework.JerseyTest;\r
+import com.sun.jersey.test.framework.WebAppDescriptor;\r
+\r
+import com.sun.jersey.api.client.Client;\r
+\r
+\r
+/**\r
+ * This suite of tests is intended to exercise the behaviour of the {@link RestClient}.\r
+ */\r
+public class RESTClientTest extends JerseyTest {\r
+\r
+  private static final String GOOD_AAI_ENDPOINT = "testaai/good";\r
+  private static final String FAIL_ALWAYS_AAI_ENDPOINT = "testaai/failalways";\r
+  private static final String FAIL_THEN_SUCCEED_ENDPOINT = "testaai/failthensucceed";\r
+  private static final String INVALID_AAI_ENDPOINT = "testaai/bad";\r
+\r
+  private static final String AAI_GET_REPLY_PAYLOAD = "Reply from AAI";\r
+\r
+  private static final int SUCCESS_RESULT_CODE = 200;\r
+  private static final int INVALID_END_POINT_RESULT_CODE = 404;\r
+  private static final int INTERNAL_ERR_RESULT_CODE = 500;\r
+  private static final int TIMEOUT_RESULT_CODE = 504;\r
+\r
+\r
+  /**\r
+   * Creates a new instance of the {@link RESTClientTest} test suite.\r
+   */\r
+  public RESTClientTest() throws Exception {\r
+\r
+    // Tell our in memory container to look here for resource endpoints.\r
+    super("org.openecomp.restclient.client");\r
+  }\r
+\r
+\r
+  @Override\r
+  protected AppDescriptor configure() {\r
+    return new WebAppDescriptor.Builder().build();\r
+  }\r
+\r
+\r
+  /**\r
+   * Perform common initialization actions that need to run before every unit test.\r
+   */\r
+  @Before\r
+  public void setup() {\r
+\r
+    // Initialize our test endpoints to make sure that all of their\r
+    // counters have valid starting values\r
+    AAI_FailAlways_Stub.initialize();\r
+    AAI_FailThenSucceed_Stub.initialize();\r
+  }\r
+\r
+\r
+  /**\r
+   * This test validates that all of the {@link RestClient}'s configurable parameters can be set via\r
+   * its fluent interface and that those values are successfully passed down to the underlying\r
+   * {@link RestClientBuilder} instance.\r
+   */\r
+  @Test\r
+  public void configureAAIClientTest() {\r
+\r
+    final boolean VALIDATE_SERVER = true;\r
+    final boolean VALIDATE_CERT_CHAIN = true;\r
+    final String CLIENT_CERT_FILE = "myCertFile";\r
+    final String CLIENT_CERT_PASSWORD = "My voice is my password";\r
+    final String TRUST_STORE = "myTrustStore";\r
+    final int CONNECT_TIMEOUT = 5000;\r
+    final int READ_TIMEOUT = 5000;\r
+\r
+    // Create an instance of our test version of the REST client builder.\r
+    TestRestClientBuilder clientBuilder = new TestRestClientBuilder();\r
+\r
+    // Now, create a new instance of the {@link AAIClient} and configure\r
+    // its parameters.\r
+    RestClient testClient =\r
+        new RestClient(clientBuilder).validateServerHostname(true).validateServerCertChain(true)\r
+            .clientCertFile("myCertFile").clientCertPassword("My voice is my password")\r
+            .trustStore("myTrustStore").connectTimeoutMs(5000).readTimeoutMs(5000);\r
+\r
+    // Validate that the parameters of the test REST client builder that\r
+    // we passed to the AAI client have been set according to what we\r
+    // passed in when we instantiated the AAI client.\r
+    assertEquals("Unexpected 'validate server host name' value", VALIDATE_SERVER,\r
+        clientBuilder.isValidateServerHostname());\r
+    assertEquals("Unexpected 'validate certificat chain' value", VALIDATE_CERT_CHAIN,\r
+        clientBuilder.isValidateServerCertChain());\r
+    assertTrue("Unexpected client certificate filename",\r
+        CLIENT_CERT_FILE.equals(clientBuilder.getClientCertFileName()));\r
+    assertTrue("Unexpected client certificate password",\r
+        CLIENT_CERT_PASSWORD.equals(clientBuilder.getClientCertPassword()));\r
+    assertTrue("Unexpected trust store filename",\r
+        TRUST_STORE.equals(clientBuilder.getTruststoreFilename()));\r
+    assertEquals("Unexpected connection timeout value", CONNECT_TIMEOUT,\r
+        clientBuilder.getConnectTimeoutInMs());\r
+    assertEquals("Unexpected read timeout value", READ_TIMEOUT, clientBuilder.getReadTimeoutInMs());\r
+  }\r
+\r
+\r
+  /**\r
+   * This test validates that the {@link RestClient} can submit a GET request to a valid REST\r
+   * endpoint and receive a valid response.\r
+   */\r
+  @Test\r
+  public void queryAAI_SuccessTest() {\r
+\r
+    // Create an instance of the AAIClient that uses our test version of\r
+    // the REST client builder.\r
+    RestClient testClient = new RestClient(new TestRestClientBuilder());\r
+\r
+    // Query our stubbed out AAI with a URL that we expecte to get a successful\r
+    // reply from.\r
+    OperationResult or =\r
+        testClient.get(getBaseURI() + GOOD_AAI_ENDPOINT, null, MediaType.APPLICATION_JSON_TYPE);\r
+\r
+    // Validate that a successful query returns a result code of 200.\r
+    assertEquals("Unexpected result code", SUCCESS_RESULT_CODE, or.getResultCode());\r
+\r
+    // Validate that no error cause gets set on a successful query.\r
+    assertNull("Operation result failure code should not be set for successful GET",\r
+        or.getFailureCause());\r
+\r
+    // Validate that our query returned the expected payload from our dummy\r
+    // AAI.\r
+    assertTrue("Incorrect payload returned from AAI query",\r
+        AAI_GET_REPLY_PAYLOAD.equals(or.getResult()));\r
+  }\r
+\r
+\r
+  /**\r
+   * This test validates that the {@link RestClient} behaves as expected when query requests are\r
+   * unsuccessful.\r
+   * <p>\r
+   * Specifically, the following scenarios are covered:<br>\r
+   * 1) Submitting a GET request to an invalid REST endpoint 2) Submitting a GET request to a valid\r
+   * endpoint which throws an error rather than replying successfully.\r
+   * <p>\r
+   * Note that this test exercises the 'single attempt' variant of the query method.\r
+   */\r
+  @Test\r
+  public void queryAAI_FailureTest() {\r
+\r
+    // Create an instance of the AAIClient that uses our test version of\r
+    // the REST client builder.\r
+    RestClient testClient = new RestClient(new TestRestClientBuilder());\r
+\r
+    // Query our stubbed out AAI with a URL that we expecte to get a successful\r
+    // reply from.\r
+    OperationResult or =\r
+        testClient.get(getBaseURI() + INVALID_AAI_ENDPOINT, null, MediaType.APPLICATION_JSON_TYPE);\r
+\r
+    // Validate that an attempt to query a non-existing endpoint results in\r
+    // a 404 error.\r
+    assertEquals("Unexpected result code", INVALID_END_POINT_RESULT_CODE, or.getResultCode());\r
+\r
+    // Validate that no payload was set since the query failed.\r
+    assertNull("Payload should not be set on 404 error", or.getResult());\r
+\r
+    // Now, submit a query request to the stubbed AAI.\r
+    or = testClient.get(getBaseURI() + FAIL_ALWAYS_AAI_ENDPOINT, null,\r
+        MediaType.APPLICATION_JSON_TYPE);\r
+\r
+    // Validate that a query to a avalid returns a result code of 500.\r
+    assertEquals("Unexpected result code", INTERNAL_ERR_RESULT_CODE, or.getResultCode());\r
+  }\r
+\r
+\r
+  /**\r
+   * This test validates the behaviour of querying the AAI with a number of retries requested in the\r
+   * case where we never get a successful reply.\r
+   */\r
+  @Test\r
+  public void queryAAIWithRetries_TimeoutTest() {\r
+\r
+    int NUM_RETRIES = 3;\r
+\r
+\r
+    // Create an instance of the AAIClient that uses our test version of\r
+    // the REST client builder.\r
+    RestClient testClient = new RestClient(new TestRestClientBuilder());\r
+\r
+    // Initialize our test endpoint to make sure that all of its\r
+    // counters have valid starting values\r
+    // AAI_FailAlways_Stub.initialize();\r
+\r
+    // Perform a query against the stubbed AAI, specifying a number of times\r
+    // to retry in the event of an error.\r
+    OperationResult or = testClient.get(getBaseURI() + FAIL_ALWAYS_AAI_ENDPOINT, null,\r
+        MediaType.APPLICATION_JSON_TYPE, NUM_RETRIES);\r
+\r
+    // Validate that failing for all of our retry attempts results in a\r
+    // 504 error.\r
+    assertEquals("Unexpected result code", TIMEOUT_RESULT_CODE, or.getResultCode());\r
+\r
+    // Validate that our stubbed AAI actually received the expected number\r
+    // of retried requests.\r
+    assertEquals("Unexpected number of retries", NUM_RETRIES, AAI_FailAlways_Stub.getCount);\r
+  }\r
+\r
+\r
+  /**\r
+   * This test validates the behaviour of querying the AAI with a number of retries requested in the\r
+   * case where our query initially fails but then succeeds on one of the subsequent retries.\r
+   */\r
+  @Test\r
+  public void queryAAIWithRetries_FailThenSucceedTest() {\r
+\r
+    int num_retries = AAI_FailThenSucceed_Stub.MAX_FAILURES + 2;\r
+\r
+    // Create an instance of the AAIClient that uses our test version of\r
+    // the REST client builder.\r
+    RestClient testClient = new RestClient(new TestRestClientBuilder());\r
+\r
+    // Initialize our test endpoint to make sure that all of its\r
+    // counters have valid starting values.\r
+    // AAI_FailThenSucceed_Stub.initialize();\r
+\r
+    // Perform a query against the stubbed AAI, specifying a number of times\r
+    // to retry in the event of an error.\r
+    OperationResult or = testClient.get(getBaseURI() + FAIL_THEN_SUCCEED_ENDPOINT, null,\r
+        MediaType.APPLICATION_JSON_TYPE, num_retries);\r
+\r
+    // Validate that after failing a few attempts we finally got back a\r
+    // success code.\r
+    assertEquals("Unexpected result code", SUCCESS_RESULT_CODE, or.getResultCode());\r
+\r
+    // Validate that our stubbed AAI actually received the expected number\r
+    // of retried requests.\r
+    assertEquals("Unexpected number of retries", AAI_FailThenSucceed_Stub.MAX_FAILURES + 1,\r
+        AAI_FailThenSucceed_Stub.getCount);\r
+  }\r
+\r
+\r
+  /**\r
+   * This class provides a simple in-memory REST end point to stand in for a real AAI.\r
+   * <p>\r
+   * This endpoint always returns a valid reply to a GET request and is used for success path\r
+   * testing.\r
+   */\r
+  @Path(GOOD_AAI_ENDPOINT)\r
+  public static class AAI_Success_Stub {\r
+\r
+    /**\r
+     * This is the end point for GET requests. It just returns a simple, pre-canned response\r
+     * payload.\r
+     * \r
+     * @return - A pre-canned response.\r
+     */\r
+    @GET\r
+    public String getEndpoint() {\r
+      return AAI_GET_REPLY_PAYLOAD;\r
+    }\r
+  }\r
+\r
+\r
+  /**\r
+   * This class provides a simple in-memory REST end point to stand in for a real AAI.\r
+   * <p>\r
+   * This endpoint always returns throws an error instead of responding successfully and is used for\r
+   * certain failure path tests.\r
+   */\r
+  @Path(FAIL_ALWAYS_AAI_ENDPOINT)\r
+  public static class AAI_FailAlways_Stub {\r
+\r
+    /**\r
+     * Maintains a running count of the number of GET requests that have been received.\r
+     */\r
+    public static int getCount;\r
+\r
+\r
+    /**\r
+     * Resets all of the endpoints counters.\r
+     */\r
+    public static void initialize() {\r
+      getCount = 0;\r
+    }\r
+\r
+\r
+    /**\r
+     * This is the end point for GET requests. It just throws an error instead of returning a valid\r
+     * response.\r
+     * \r
+     * @return - NONE. We actually throw an exception intentionally instead of returning.\r
+     */\r
+    @GET\r
+    public String getEndpoint() {\r
+\r
+      // Keep track of the number of get requests that we have received\r
+      // so that this value can be used for validation purposes later.\r
+      getCount++;\r
+\r
+      // Always just throw an error instead of replying successfully.\r
+      throw new UnsupportedOperationException("Intentional Failure");\r
+    }\r
+  }\r
+\r
+\r
+  /**\r
+   * This class provides a simple in-memory REST end point to stand in for a real AAI.\r
+   * <p>\r
+   * This end point will throw errors instead of responding for a certain number of requests, after\r
+   * which it will return a valid, pre-canned response.\r
+   * \r
+   * @return - A pre-canned response.\r
+   */\r
+  @Path(FAIL_THEN_SUCCEED_ENDPOINT)\r
+  public static class AAI_FailThenSucceed_Stub {\r
+\r
+    /**\r
+     * The number of requests for which we should throw errors before responding successfully.\r
+     */\r
+    public static int MAX_FAILURES = 2;\r
+\r
+    /**\r
+     * Maintains a running count of the number of GET requests that have been received.\r
+     */\r
+    public static int getCount;\r
+\r
+    /**\r
+     * Maintains a running count of the number of requests which we have failed, so that we will\r
+     * know when to stop failing and return a valid response.\r
+     */\r
+    private static int failCount;\r
+\r
+\r
+    /**\r
+     * Resets all of the endpoints counters.\r
+     */\r
+    public static void initialize() {\r
+      getCount = 0;\r
+      failCount = 0;\r
+    }\r
+\r
+\r
+    /**\r
+     * This is the end point for GET requests. It will throw errors for a certain number of requests\r
+     * and then return a valid response.\r
+     * \r
+     * @return - A pre-canned response string.\r
+     */\r
+    @GET\r
+    public String getEndpoint() {\r
+\r
+      // Keep track of the number of get requests that we have received\r
+      // so that this value can be used for validation purposes later.\r
+      getCount++;\r
+\r
+      // We only want to fail a set number of times, so check now to\r
+      // see what we should do.\r
+      if (failCount < MAX_FAILURES) {\r
+        failCount++;\r
+        throw new UnsupportedOperationException("Intentional Failure");\r
+\r
+      } else {\r
+        // We've failed as often as we need to. Time to reply\r
+        // successfully.\r
+        failCount = 0;\r
+        return AAI_GET_REPLY_PAYLOAD;\r
+      }\r
+    }\r
+  }\r
+\r
+\r
+  /**\r
+   * This class overrides the behaviour of the {@link RestClientBuilder} used by the\r
+   * {@link RestClient} to just return the in memory client provided by the JerseyTest framework.\r
+   */\r
+  private class TestRestClientBuilder extends RestClientBuilder {\r
+\r
+    @Override\r
+    public Client getClient() throws Exception {\r
+      return client();\r
+    }\r
+  }\r
+}\r