Skip to content

Commit

Permalink
Merge pull request #547 from daliboz/master
Browse files Browse the repository at this point in the history
Fix #546 CapturingInterceptor will now buffer response
  • Loading branch information
jamesagnew committed Jan 31, 2017
2 parents 11f1f4f + c1e6f82 commit ea1ebb2
Show file tree
Hide file tree
Showing 2 changed files with 169 additions and 2 deletions.
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());
}

}

0 comments on commit ea1ebb2

Please sign in to comment.