Search in sources :

Example 1 with HttpConnectionInterceptorContext

use of com.cloudant.http.HttpConnectionInterceptorContext in project java-cloudant by cloudant.

the class HttpTest method testHttpConnectionRetries.

/**
 * Test the global number of retries
 *
 * @throws Exception
 */
@TestTemplate
public void testHttpConnectionRetries() throws Exception {
    // Just return 200 OK
    mockWebServer.setDispatcher(new MockWebServerResources.ConstantResponseDispatcher(200));
    CloudantClient c = CloudantClientHelper.newMockWebServerClientBuilder(mockWebServer).interceptors(new HttpConnectionResponseInterceptor() {

        @Override
        public HttpConnectionInterceptorContext interceptResponse(HttpConnectionInterceptorContext context) {
            // At least do something with the connection, otherwise we risk breaking it
            try {
                context.connection.getConnection().getResponseCode();
            } catch (IOException e) {
                fail("IOException getting response code");
            }
            // Set to always replay
            context.replayRequest = true;
            return context;
        }
    }).build();
    String response = c.executeRequest(Http.GET(c.getBaseUri()).setNumberOfRetries(5)).responseAsString();
    assertTrue(response.isEmpty(), "There should be no response body on the mock response");
    assertEquals(5, mockWebServer.getRequestCount(), "There should be 5 request attempts");
}
Also used : CloudantClient(com.cloudant.client.api.CloudantClient) HttpConnectionResponseInterceptor(com.cloudant.http.HttpConnectionResponseInterceptor) IOException(java.io.IOException) CoreMatchers.containsString(org.hamcrest.CoreMatchers.containsString) MockWebServerResources(com.cloudant.tests.util.MockWebServerResources) HttpConnectionInterceptorContext(com.cloudant.http.HttpConnectionInterceptorContext) TestTemplate(org.junit.jupiter.api.TestTemplate)

Example 2 with HttpConnectionInterceptorContext

use of com.cloudant.http.HttpConnectionInterceptorContext in project java-cloudant by cloudant.

the class Utils method removeReplicatorTestDoc.

public static void removeReplicatorTestDoc(CloudantClient account, String replicatorDocId) throws Exception {
    // Grab replicator doc revision using HTTP HEAD command
    String replicatorDb = "_replicator";
    URI uri = new URIBase(account.getBaseUri()).path(replicatorDb).path(replicatorDocId).build();
    HttpConnection head = Http.HEAD(uri);
    // add a response interceptor to allow us to retrieve the ETag revision header
    final AtomicReference<String> revisionRef = new AtomicReference<String>();
    head.responseInterceptors.add(new HttpConnectionResponseInterceptor() {

        @Override
        public HttpConnectionInterceptorContext interceptResponse(HttpConnectionInterceptorContext context) {
            revisionRef.set(context.connection.getConnection().getHeaderField("ETag"));
            return context;
        }
    });
    account.executeRequest(head);
    String revision = revisionRef.get();
    assertNotNull("The revision should not be null", revision);
    Database replicator = account.database(replicatorDb, false);
    Response removeResponse = replicator.remove(replicatorDocId, revision.replaceAll("\"", ""));
    assertThat(removeResponse.getError(), is(nullValue()));
}
Also used : Response(com.cloudant.client.api.model.Response) HttpConnection(com.cloudant.http.HttpConnection) Database(com.cloudant.client.api.Database) AtomicReference(java.util.concurrent.atomic.AtomicReference) HttpConnectionResponseInterceptor(com.cloudant.http.HttpConnectionResponseInterceptor) HttpConnectionInterceptorContext(com.cloudant.http.HttpConnectionInterceptorContext) URI(java.net.URI) URIBase(com.cloudant.client.internal.URIBase)

Example 3 with HttpConnectionInterceptorContext

use of com.cloudant.http.HttpConnectionInterceptorContext in project java-cloudant by cloudant.

the class HttpTest method testInputStreamRetry.

private void testInputStreamRetry(HttpConnection request, byte[] expectedContent) throws Exception {
    final MockResponse retry = new MockResponse().setResponseCode(444);
    mockWebServer.enqueue(retry);
    mockWebServer.enqueue(new MockResponse());
    HttpConnection response = CloudantClientHelper.newMockWebServerClientBuilder(mockWebServer).interceptors(new HttpConnectionResponseInterceptor() {

        // This interceptor responds to our 444 request with a retry
        @Override
        public HttpConnectionInterceptorContext interceptResponse(HttpConnectionInterceptorContext context) {
            try {
                if (444 == context.connection.getConnection().getResponseCode()) {
                    context.replayRequest = true;
                    // Close the error stream
                    InputStream errors = context.connection.getConnection().getErrorStream();
                    if (errors != null) {
                        IOUtils.closeQuietly(errors);
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
                fail("IOException getting response code in test interceptor");
            }
            return context;
        }
    }).build().executeRequest(request);
    String responseStr = response.responseAsString();
    assertTrue(responseStr.isEmpty(), "There should be no response body on the mock response");
    assertEquals(200, response.getConnection().getResponseCode(), "The final response code should be 200");
    // We want the second request
    assertEquals(2, mockWebServer.getRequestCount(), "There should have been two requests");
    MockWebServerResources.takeRequestWithTimeout(mockWebServer);
    RecordedRequest rr = MockWebServerResources.takeRequestWithTimeout(mockWebServer);
    assertNotNull(rr, "The request should have been recorded");
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream((int) rr.getBodySize());
    rr.getBody().copyTo(byteArrayOutputStream);
    assertArrayEquals(expectedContent, byteArrayOutputStream.toByteArray(), "The body bytes should have matched after a " + "retry");
}
Also used : RecordedRequest(okhttp3.mockwebserver.RecordedRequest) MockResponse(okhttp3.mockwebserver.MockResponse) HttpConnection(com.cloudant.http.HttpConnection) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) HttpConnectionResponseInterceptor(com.cloudant.http.HttpConnectionResponseInterceptor) IOException(java.io.IOException) CoreMatchers.containsString(org.hamcrest.CoreMatchers.containsString) ByteArrayOutputStream(java.io.ByteArrayOutputStream) HttpConnectionInterceptorContext(com.cloudant.http.HttpConnectionInterceptorContext)

Example 4 with HttpConnectionInterceptorContext

use of com.cloudant.http.HttpConnectionInterceptorContext in project java-cloudant by cloudant.

the class HttpTest method testCustomHeader.

@TestTemplate
public void testCustomHeader() throws Exception {
    mockWebServer.enqueue(new MockResponse());
    final String headerName = "Test-Header";
    final String headerValue = "testHeader";
    CloudantClient client = CloudantClientHelper.newMockWebServerClientBuilder(mockWebServer).interceptors(new HttpConnectionRequestInterceptor() {

        @Override
        public HttpConnectionInterceptorContext interceptRequest(HttpConnectionInterceptorContext context) {
            context.connection.requestProperties.put(headerName, headerValue);
            return context;
        }
    }).build();
    client.getAllDbs();
    assertEquals(1, mockWebServer.getRequestCount(), "There should have been 1 request");
    RecordedRequest request = MockWebServerResources.takeRequestWithTimeout(mockWebServer);
    assertNotNull(request, "The recorded request should not be null");
    assertNotNull(request.getHeader(headerName), "The custom header should have been present");
    assertEquals(headerValue, request.getHeader(headerName), "The custom header should have the specified value");
}
Also used : HttpConnectionRequestInterceptor(com.cloudant.http.HttpConnectionRequestInterceptor) RecordedRequest(okhttp3.mockwebserver.RecordedRequest) MockResponse(okhttp3.mockwebserver.MockResponse) CloudantClient(com.cloudant.client.api.CloudantClient) CoreMatchers.containsString(org.hamcrest.CoreMatchers.containsString) HttpConnectionInterceptorContext(com.cloudant.http.HttpConnectionInterceptorContext) TestTemplate(org.junit.jupiter.api.TestTemplate)

Example 5 with HttpConnectionInterceptorContext

use of com.cloudant.http.HttpConnectionInterceptorContext in project java-cloudant by cloudant.

the class ResponseTest method testJsonErrorStreamFromLB.

/**
 * Test that an error stream is correctly assigned to a CouchDbException error field if it comes
 * directly from the lb and not the service.
 * <P>
 * This is a Cloudant service test, where a HTTP proxy may send an error.
 * We can provoke it into doing so by sending an invalid HTTP request - in this case an
 * invalid header field.
 * Originally these errors were wrapped in HTML and so exercised a different path - they are now
 * JSON body responses like most other Cloudant requests so should be on the normal exception
 * handling path, but it is worth checking that we do work with these error types.
 * </P>
 */
@RequiresCloudant
@Test
public void testJsonErrorStreamFromLB() throws Exception {
    final AtomicBoolean badHeaderEnabled = new AtomicBoolean(false);
    CloudantClient c = CloudantClientHelper.getClientBuilder().interceptors(new HttpConnectionRequestInterceptor() {

        @Override
        public HttpConnectionInterceptorContext interceptRequest(HttpConnectionInterceptorContext context) {
            if (badHeaderEnabled.get()) {
                // Note space is also a bad char, but OkHttp prohibits them
                String badHeaderCharacters = "()<>@,;\\/[]?=";
                // set a header using characters that are not permitted
                context.connection.requestProperties.put(badHeaderCharacters, badHeaderCharacters);
            }
            return context;
        }
    }).build();
    try {
        // Make a good request, which will set up the session etc
        HttpConnection d = c.executeRequest(Http.GET(c.getBaseUri()));
        d.responseAsString();
        assertTrue(d.getConnection().getResponseCode() / 100 == 2, "The first request should " + "succeed");
        // Enable the bad headers and expect the exception on the next request
        badHeaderEnabled.set(true);
        String response = c.executeRequest(Http.GET(c.getBaseUri())).responseAsString();
        fail("A CouchDbException should be thrown, but had response " + response);
    } catch (CouchDbException e) {
        // we expect a CouchDbException
        assertEquals(400, e.getStatusCode(), "The exception should be for a bad request");
        assertNotNull(e.getError(), "The exception should have an error set");
        assertEquals("bad_request", e.getError(), "The exception error should be bad request");
    } finally {
        // Disable the bad header to allow a clean shutdown
        badHeaderEnabled.set(false);
        c.shutdown();
    }
}
Also used : HttpConnectionRequestInterceptor(com.cloudant.http.HttpConnectionRequestInterceptor) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) CouchDbException(com.cloudant.client.org.lightcouch.CouchDbException) CloudantClient(com.cloudant.client.api.CloudantClient) HttpConnection(com.cloudant.http.HttpConnection) HttpConnectionInterceptorContext(com.cloudant.http.HttpConnectionInterceptorContext) Test(org.junit.jupiter.api.Test) RequiresCloudant(com.cloudant.test.main.RequiresCloudant)

Aggregations

HttpConnectionInterceptorContext (com.cloudant.http.HttpConnectionInterceptorContext)6 CloudantClient (com.cloudant.client.api.CloudantClient)3 HttpConnection (com.cloudant.http.HttpConnection)3 HttpConnectionResponseInterceptor (com.cloudant.http.HttpConnectionResponseInterceptor)3 CoreMatchers.containsString (org.hamcrest.CoreMatchers.containsString)3 HttpConnectionRequestInterceptor (com.cloudant.http.HttpConnectionRequestInterceptor)2 IOException (java.io.IOException)2 MockResponse (okhttp3.mockwebserver.MockResponse)2 RecordedRequest (okhttp3.mockwebserver.RecordedRequest)2 Test (org.junit.jupiter.api.Test)2 TestTemplate (org.junit.jupiter.api.TestTemplate)2 Database (com.cloudant.client.api.Database)1 Response (com.cloudant.client.api.model.Response)1 URIBase (com.cloudant.client.internal.URIBase)1 CouchDbException (com.cloudant.client.org.lightcouch.CouchDbException)1 RequiresCloudant (com.cloudant.test.main.RequiresCloudant)1 TestWithDbPerTest (com.cloudant.tests.base.TestWithDbPerTest)1 MockWebServerResources (com.cloudant.tests.util.MockWebServerResources)1 JsonObject (com.google.gson.JsonObject)1 ByteArrayInputStream (java.io.ByteArrayInputStream)1