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");
}
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()));
}
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");
}
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");
}
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();
}
}
Aggregations