Search in sources :

Example 21 with CloudantClient

use of com.cloudant.client.api.CloudantClient in project java-cloudant by cloudant.

the class ViewsTest method getIdsAndRevsForDeletedIDsWithAllDocs.

/**
 * <p>
 * Test added for https://github.com/cloudant/java-cloudant/issues/411
 * </p>
 * <p>
 * When _all_docs is used with specified keys deleted documents are also returned. The value of
 * total_rows may represent only the un-deleted documents meaning more rows are returned than
 * total_rows. This total_rows variance doesn't always manifest so we reproduce it using a mock.
 * </p>
 *
 * @throws Exception
 */
@Test
public void getIdsAndRevsForDeletedIDsWithAllDocs() throws Exception {
    Map<String, String> idsAndRevs = new HashMap<String, String>(4);
    idsAndRevs.put("docid0", "1-a00e6463d52d7f167c8ac5c834836c1b");
    idsAndRevs.put("docid1", "1-a00e6463d52d7f167c8ac5c834836c1b");
    idsAndRevs.put("docid2", "2-acbb972b187ec952eae1ca74cfef16a9");
    idsAndRevs.put("docid3", "2-acbb972b187ec952eae1ca74cfef16a9");
    CloudantClient client = CloudantClientHelper.newMockWebServerClientBuilder(mockWebServer).build();
    Database database = client.database("deletedidsalldocskeysdb", false);
    // _all_docs?keys=["docid0", "docid1", "docid2", "docid3"]
    MockResponse mockResponse = new MockResponse().setResponseCode(200).setBody("{\"total_rows\":2,\"offset\":0,\"rows\":[\n" + "{\"id\":\"docid0\",\"key\":\"docid0\"," + "\"value\":{\"rev\":\"1-a00e6463d52d7f167c8ac5c834836c1b\"}},\n" + "{\"id\":\"docid1\",\"key\":\"docid1\"," + "\"value\":{\"rev\":\"1-a00e6463d52d7f167c8ac5c834836c1b\"}},\n" + "{\"id\":\"docid2\",\"key\":\"docid2\"," + "\"value\":{\"rev\":\"2-acbb972b187ec952eae1ca74cfef16a9\"," + "\"deleted\":true}},\n" + "{\"id\":\"docid3\",\"key\":\"docid3\"," + "\"value\":{\"rev\":\"2-acbb972b187ec952eae1ca74cfef16a9\"," + "\"deleted\":true}}\n" + "]}");
    mockWebServer.enqueue(mockResponse);
    // Do an _all_docs request using the 4 _ids of the generated docs.
    Map<String, String> allDocsIdsAndRevs = database.getAllDocsRequestBuilder().keys(idsAndRevs.keySet().toArray(new String[4])).build().getResponse().getIdsAndRevs();
    assertEquals(idsAndRevs, allDocsIdsAndRevs, "The ids and revs should be equal");
}
Also used : MockResponse(okhttp3.mockwebserver.MockResponse) CloudantClient(com.cloudant.client.api.CloudantClient) HashMap(java.util.HashMap) Database(com.cloudant.client.api.Database) TestWithDbPerTest(com.cloudant.tests.base.TestWithDbPerTest) Test(org.junit.jupiter.api.Test)

Example 22 with CloudantClient

use of com.cloudant.client.api.CloudantClient in project java-cloudant by cloudant.

the class ViewRequester method executeRequestWithResponseAsJson.

static JsonObject executeRequestWithResponseAsJson(ViewQueryParameters parameters, HttpConnection request) throws IOException {
    CloudantClient client = parameters.getClient();
    InputStream response = client.executeRequest(request).responseAsInputStream();
    return CouchDbUtil.getResponse(response, JsonObject.class, client.getGson());
}
Also used : CloudantClient(com.cloudant.client.api.CloudantClient) InputStream(java.io.InputStream)

Example 23 with CloudantClient

use of com.cloudant.client.api.CloudantClient in project java-cloudant by cloudant.

the class HttpIamTest method iamTokenAndCookieWithExpirySuccessful.

/**
 * Test IAM token and cookie flow, where session expires and is successfully renewed:
 * - GET a resource on the cloudant server
 * - Cookie jar empty, so get IAM token followed by session cookie
 * - GET now proceeds as normal, expected cookie value is sent in header
 * - second GET on cloudant server, re-using session cookie
 * - third GET on cloudant server, cookie expired, get IAM token and session cookie and replay
 * request
 *
 * @throws Exception
 */
@Test
public void iamTokenAndCookieWithExpirySuccessful() throws Exception {
    // Request sequence
    mockWebServer.enqueue(OK_IAM_COOKIE);
    mockWebServer.enqueue(new MockResponse().setResponseCode(200).setBody(hello));
    mockWebServer.enqueue(new MockResponse().setResponseCode(200).setBody(hello));
    // cookie expired
    mockWebServer.enqueue(new MockResponse().setResponseCode(401).setBody("{\"error\":\"credentials_expired\"}"));
    // response with new cookie
    mockWebServer.enqueue(OK_IAM_COOKIE_2);
    mockWebServer.enqueue(new MockResponse().setResponseCode(200).setBody(hello));
    mockIamServer.enqueue(new MockResponse().setResponseCode(200).setBody(IAM_TOKEN));
    mockIamServer.enqueue(new MockResponse().setResponseCode(200).setBody(IAM_TOKEN_2));
    CloudantClient c = CloudantClientHelper.newMockWebServerClientBuilder(mockWebServer).iamApiKey(iamApiKey).build();
    String response = c.executeRequest(Http.GET(c.getBaseUri())).responseAsString();
    assertEquals(hello, response, "The expected response should be received");
    String response2 = c.executeRequest(Http.GET(c.getBaseUri())).responseAsString();
    assertEquals(hello, response2, "The expected response should be received");
    String response3 = c.executeRequest(Http.GET(c.getBaseUri())).responseAsString();
    assertEquals(hello, response3, "The expected response should be received");
    // cloudant mock server
    // assert that there were 6 calls
    RecordedRequest[] recordedRequests = takeN(mockWebServer, 6);
    assertEquals("/_iam_session", recordedRequests[0].getPath(), "The request should have been for /_iam_session");
    assertThat("The request body should contain the IAM token", recordedRequests[0].getBody().readString(Charset.forName("UTF-8")), containsString(IAM_TOKEN));
    // first request
    assertEquals("/", recordedRequests[1].getPath(), "The request should have been for /");
    // The cookie may or may not have the session id quoted, so check both
    assertThat("The Cookie header should contain the expected session value", recordedRequests[1].getHeader("Cookie"), anyOf(containsString(iamSession(EXPECTED_OK_COOKIE)), containsString(iamSessionUnquoted(EXPECTED_OK_COOKIE))));
    // second request
    assertEquals("/", recordedRequests[2].getPath(), "The request should have been for /");
    // third request, will be rejected due to cookie expiry
    assertEquals("/", recordedRequests[3].getPath(), "The request should have been for /");
    // renew cookie after third request fails
    assertEquals("/_iam_session", recordedRequests[4].getPath(), "The request should have been for /_iam_session");
    assertThat("The request body should contain the IAM token", recordedRequests[4].getBody().readString(Charset.forName("UTF-8")), containsString(IAM_TOKEN_2));
    // replay of third request
    assertEquals("/", recordedRequests[5].getPath(), "The request should have been for /");
    // The (new) cookie may or may not have the session id quoted, so check both
    assertThat("The Cookie header should contain the expected session value", recordedRequests[5].getHeader("Cookie"), anyOf(containsString(iamSession(EXPECTED_OK_COOKIE_2)), containsString(iamSessionUnquoted(EXPECTED_OK_COOKIE_2))));
    // iam mock server
    // assert that there were 2 calls
    RecordedRequest[] recordedIamRequests = takeN(mockIamServer, 2);
    // first time, automatically fetch because cookie jar is empty
    assertEquals(iamTokenEndpoint, recordedIamRequests[0].getPath(), "The request should have been for " + "/identity/token");
    assertThat("The request body should contain the IAM API key", recordedIamRequests[0].getBody().readString(Charset.forName("UTF-8")), containsString("apikey=" + iamApiKey));
    // second time, refresh because the cloudant session cookie has expired
    assertEquals(iamTokenEndpoint, recordedIamRequests[1].getPath(), "The request should have been for " + "/identity/token");
}
Also used : RecordedRequest(okhttp3.mockwebserver.RecordedRequest) MockResponse(okhttp3.mockwebserver.MockResponse) CloudantClient(com.cloudant.client.api.CloudantClient) CoreMatchers.containsString(org.hamcrest.CoreMatchers.containsString) Test(org.junit.jupiter.api.Test)

Example 24 with CloudantClient

use of com.cloudant.client.api.CloudantClient in project java-cloudant by cloudant.

the class HttpIamTest method iamRenewalFailureOnIamToken.

/**
 * Test IAM token and cookie flow, where session expires and subsequent IAM token fails:
 * - GET a resource on the cloudant server
 * - Cookie jar empty, so get IAM token followed by session cookie
 * - GET now proceeds as normal, expected cookie value is sent in header
 * - second GET on cloudant server, re-using session cookie
 * - third GET on cloudant server, cookie expired, subsequent IAM token fails, no more requests
 * are made
 *
 * @throws Exception
 */
@Test
public void iamRenewalFailureOnIamToken() throws Exception {
    // Request sequence
    mockWebServer.enqueue(OK_IAM_COOKIE);
    mockWebServer.enqueue(new MockResponse().setResponseCode(200).setBody(hello));
    mockWebServer.enqueue(new MockResponse().setResponseCode(200).setBody(hello));
    // cookie expired
    mockWebServer.enqueue(new MockResponse().setResponseCode(401).setBody("{\"error\":\"credentials_expired\"}"));
    mockIamServer.enqueue(new MockResponse().setResponseCode(200).setBody(IAM_TOKEN));
    // mock IAM going down randomly
    mockIamServer.enqueue(new MockResponse().setResponseCode(500));
    CloudantClient c = CloudantClientHelper.newMockWebServerClientBuilder(mockWebServer).iamApiKey(iamApiKey).build();
    String response = c.executeRequest(Http.GET(c.getBaseUri())).responseAsString();
    assertEquals(hello, response, "The expected response should be received");
    String response2 = c.executeRequest(Http.GET(c.getBaseUri())).responseAsString();
    assertEquals(hello, response2, "The expected response should be received");
    // unhelpful
    try {
        c.executeRequest(Http.GET(c.getBaseUri())).responseAsString();
        fail("Should get CouchDbException when trying to get response");
    } catch (CouchDbException cdbe) {
        ;
    }
    // cloudant mock server
    // assert that there were 4 calls
    RecordedRequest[] recordedRequests = takeN(mockWebServer, 4);
    assertEquals("/_iam_session", recordedRequests[0].getPath(), "The request should have been for /_iam_session");
    assertThat("The request body should contain the IAM token", recordedRequests[0].getBody().readString(Charset.forName("UTF-8")), containsString(IAM_TOKEN));
    // first request
    assertEquals("/", recordedRequests[1].getPath(), "The request should have been for /");
    // The cookie may or may not have the session id quoted, so check both
    assertThat("The Cookie header should contain the expected session value", recordedRequests[1].getHeader("Cookie"), anyOf(containsString(iamSession(EXPECTED_OK_COOKIE)), containsString(iamSessionUnquoted(EXPECTED_OK_COOKIE))));
    // second request
    assertEquals("/", recordedRequests[2].getPath(), "The request should have been for /");
    // third request, will be rejected due to cookie expiry
    assertEquals("/", recordedRequests[3].getPath(), "The request should have been for /");
    // iam mock server
    // assert that there were 2 calls
    RecordedRequest[] recordedIamRequests = takeN(mockIamServer, 2);
    // first time, automatically fetch because cookie jar is empty
    assertEquals(iamTokenEndpoint, recordedIamRequests[0].getPath(), "The request should have been for " + "/identity/token");
    assertThat("The request body should contain the IAM API key", recordedIamRequests[0].getBody().readString(Charset.forName("UTF-8")), containsString("apikey=" + iamApiKey));
    // second time, refresh (but gets 500) because the cloudant session cookie has expired
    assertEquals(iamTokenEndpoint, recordedIamRequests[1].getPath(), "The request should have been for " + "/identity/token");
}
Also used : RecordedRequest(okhttp3.mockwebserver.RecordedRequest) MockResponse(okhttp3.mockwebserver.MockResponse) CouchDbException(com.cloudant.client.org.lightcouch.CouchDbException) CloudantClient(com.cloudant.client.api.CloudantClient) CoreMatchers.containsString(org.hamcrest.CoreMatchers.containsString) Test(org.junit.jupiter.api.Test)

Example 25 with CloudantClient

use of com.cloudant.client.api.CloudantClient in project java-cloudant by cloudant.

the class HttpIamTest method iamApiKeyPreferredToUsernamePassword.

/**
 * Assert that the IAM API key is preferred to username/password if both are supplied.
 * As above test but with different builder arguments.
 *
 * @throws Exception
 */
@Test
public void iamApiKeyPreferredToUsernamePassword() throws Exception {
    // Request sequence
    // _iam_session request to get Cookie
    // GET request -> 200 with a Set-Cookie
    mockWebServer.enqueue(OK_IAM_COOKIE);
    mockWebServer.enqueue(new MockResponse().setResponseCode(200).setBody(hello));
    mockIamServer.enqueue(new MockResponse().setResponseCode(200).setBody(IAM_TOKEN));
    CloudantClient c = CloudantClientHelper.newMockWebServerClientBuilder(mockWebServer).username("username").password("password").iamApiKey(iamApiKey).build();
    String response = c.executeRequest(Http.GET(c.getBaseUri())).responseAsString();
    assertEquals(hello, response, "The expected response should be received");
    // cloudant mock server
    // assert that there were 2 calls
    RecordedRequest[] recordedRequests = takeN(mockWebServer, 2);
    assertEquals("/_iam_session", recordedRequests[0].getPath(), "The request should have been for /_iam_session");
    assertThat("The request body should contain the IAM token", recordedRequests[0].getBody().readString(Charset.forName("UTF-8")), containsString(IAM_TOKEN));
    // the request should have the cookie header
    assertEquals("/", recordedRequests[1].getPath(), "The request should have been for /");
    // The cookie may or may not have the session id quoted, so check both
    assertThat("The Cookie header should contain the expected session value", recordedRequests[1].getHeader("Cookie"), anyOf(containsString(iamSession(EXPECTED_OK_COOKIE)), containsString(iamSessionUnquoted(EXPECTED_OK_COOKIE))));
    // asserts on the IAM server
    // assert that there was 1 call
    RecordedRequest[] recordedIamRequests = takeN(mockIamServer, 1);
    assertEquals(iamTokenEndpoint, recordedIamRequests[0].getPath(), "The request should have been for " + "/identity/token");
    assertThat("The request body should contain the IAM API key", recordedIamRequests[0].getBody().readString(Charset.forName("UTF-8")), containsString("apikey=" + iamApiKey));
}
Also used : RecordedRequest(okhttp3.mockwebserver.RecordedRequest) MockResponse(okhttp3.mockwebserver.MockResponse) CloudantClient(com.cloudant.client.api.CloudantClient) CoreMatchers.containsString(org.hamcrest.CoreMatchers.containsString) Test(org.junit.jupiter.api.Test)

Aggregations

CloudantClient (com.cloudant.client.api.CloudantClient)47 MockResponse (okhttp3.mockwebserver.MockResponse)32 TestTemplate (org.junit.jupiter.api.TestTemplate)23 CoreMatchers.containsString (org.hamcrest.CoreMatchers.containsString)21 Test (org.junit.jupiter.api.Test)20 RecordedRequest (okhttp3.mockwebserver.RecordedRequest)19 Database (com.cloudant.client.api.Database)8 CouchDbException (com.cloudant.client.org.lightcouch.CouchDbException)7 TestTimer (com.cloudant.tests.util.TestTimer)4 URL (java.net.URL)4 TooManyRequestsException (com.cloudant.client.org.lightcouch.TooManyRequestsException)3 HttpConnection (com.cloudant.http.HttpConnection)3 HttpConnectionInterceptorContext (com.cloudant.http.HttpConnectionInterceptorContext)3 Replay429Interceptor (com.cloudant.http.interceptors.Replay429Interceptor)3 Dispatcher (okhttp3.mockwebserver.Dispatcher)3 HttpConnectionRequestInterceptor (com.cloudant.http.HttpConnectionRequestInterceptor)2 BasicAuthInterceptor (com.cloudant.http.interceptors.BasicAuthInterceptor)2 RequiresCloudant (com.cloudant.test.main.RequiresCloudant)2 RequiresCloudantService (com.cloudant.test.main.RequiresCloudantService)2 TestWithDbPerTest (com.cloudant.tests.base.TestWithDbPerTest)2