Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #546 CapturingInterceptor will now buffer response #547

Merged
merged 1 commit into from Jan 31, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -23,6 +23,11 @@
import ca.uhn.fhir.rest.client.IClientInterceptor;
import ca.uhn.fhir.rest.client.api.IHttpRequest;
import ca.uhn.fhir.rest.client.api.IHttpResponse;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;

import java.io.IOException;

/**
* Client interceptor which simply captures request and response objects and stores them so that they can be inspected after a client
Expand Down Expand Up @@ -55,8 +60,23 @@ public void interceptRequest(IHttpRequest theRequest) {
}

@Override
public void interceptResponse(IHttpResponse theRequest) {
myLastResponse = theRequest;
public void interceptResponse(IHttpResponse theResponse) {
//Buffer the reponse to avoid errors when content has already been read and the entity is not repeatable
try {
if(theResponse.getResponse() instanceof HttpResponse) {
HttpEntity entity = ((HttpResponse) theResponse.getResponse()).getEntity();
if( entity != null && !entity.isRepeatable()){
theResponse.bufferEntity();
}
} else {
theResponse.bufferEntity();
}
} catch (IOException e) {
throw new InternalErrorException("Unable to buffer the entity for capturing", e);
}


myLastResponse = theResponse;
}

}
@@ -0,0 +1,147 @@
package ca.uhn.fhir.rest.client;

import ca.uhn.fhir.rest.client.apache.ApacheHttpResponse;
import ca.uhn.fhir.rest.client.api.IHttpRequest;
import ca.uhn.fhir.rest.client.api.IHttpResponse;
import ca.uhn.fhir.rest.client.interceptor.CapturingInterceptor;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.HttpVersion;
import org.apache.http.entity.BasicHttpEntity;
import org.apache.http.entity.InputStreamEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.message.BasicHttpRequest;
import org.apache.http.message.BasicHttpResponse;
import org.junit.After;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.mockito.Spy;

import java.io.IOException;
import java.nio.charset.Charset;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.*;


public class CapturingInterceptorTest {

@Rule
public ExpectedException thrown = ExpectedException.none();


@Test
public void testRequest() {
IHttpRequest expectedRequest = mock(IHttpRequest.class);

CapturingInterceptor interceptor = new CapturingInterceptor();
interceptor.interceptRequest(expectedRequest);

assertEquals(expectedRequest, interceptor.getLastRequest());
}

@Test
public void testResponse() throws Exception {
IHttpResponse expectedResponse = mock(IHttpResponse.class);
doNothing().when(expectedResponse).bufferEntity();

CapturingInterceptor interceptor = new CapturingInterceptor();
interceptor.interceptResponse(expectedResponse);

assertEquals(expectedResponse, interceptor.getLastResponse());
verify(expectedResponse).bufferEntity();
}

@Test
public void testResponseException() throws Exception {
IHttpResponse response = mock(IHttpResponse.class);
IOException expectedCause = new IOException();
doThrow(expectedCause).when(response).bufferEntity();

thrown.expect(InternalErrorException.class);
thrown.expectMessage("Unable to buffer the entity for capturing");
thrown.expectCause(equalTo(expectedCause));

CapturingInterceptor interceptor = new CapturingInterceptor();
interceptor.interceptResponse(response);
}

@Test
public void testResponseBufferApache() throws Exception{
HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
response.setEntity(new InputStreamEntity(IOUtils.toInputStream("Some content", Charset.defaultCharset())));
IHttpResponse expectedResponse = spy(new ApacheHttpResponse(response));

CapturingInterceptor interceptor = new CapturingInterceptor();
interceptor.interceptResponse(expectedResponse);
IHttpResponse actualResponse = interceptor.getLastResponse();

assertEquals(expectedResponse, actualResponse);
assertThat("Some content", equalTo(IOUtils.toString(actualResponse.createReader())));
verify(expectedResponse).bufferEntity();

//A second call should not throw an exception (InpuStreamEntity is not repeatable)
IOUtils.toString(actualResponse.createReader());
}

@Test
public void testResponseRepeatable() throws Exception{
HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
response.setEntity(new StringEntity("Some content"));
IHttpResponse expectedResponse = spy(new ApacheHttpResponse(response));

CapturingInterceptor interceptor = new CapturingInterceptor();
interceptor.interceptResponse(expectedResponse);
IHttpResponse actualResponse = interceptor.getLastResponse();

assertEquals(expectedResponse, actualResponse);
assertThat("Some content", equalTo(IOUtils.toString(actualResponse.createReader())));
verify(expectedResponse, times(0)).bufferEntity();

//A second call should not throw an exception (StringEntity is repeatable)
IOUtils.toString(actualResponse.createReader());
}

@Test
public void testResponseBufferOther() throws Exception {
Object response = mock(Object.class);
IHttpResponse expectedResponse = mock(IHttpResponse.class);
when(expectedResponse.getResponse()).thenReturn(response);
doNothing().when(expectedResponse).bufferEntity();

CapturingInterceptor interceptor = new CapturingInterceptor();
interceptor.interceptResponse(expectedResponse);
IHttpResponse actualResponse = interceptor.getLastResponse();

assertEquals(expectedResponse, actualResponse);
verify(expectedResponse).bufferEntity();
}

@Test
public void testClear(){
IHttpRequest expectedRequest = mock(IHttpRequest.class);
IHttpResponse expectedResponse = mock(IHttpResponse.class);
Object response = mock(Object.class);
when(expectedResponse.getResponse()).thenReturn(response);

CapturingInterceptor interceptor = new CapturingInterceptor();
interceptor.interceptResponse(expectedResponse);
interceptor.interceptRequest(expectedRequest);

assertEquals(expectedRequest, interceptor.getLastRequest());
assertEquals(expectedResponse, interceptor.getLastResponse());

interceptor.clear();

assertNull(interceptor.getLastRequest());
assertNull(interceptor.getLastResponse());
}

}