Include Location header details in non-verbose response for client

interceptor
This commit is contained in:
James Agnew 2017-09-06 06:26:41 -07:00
parent 7eb86d3eaa
commit 989246f0da
4 changed files with 49 additions and 3 deletions

View File

@ -26,6 +26,7 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import ca.uhn.fhir.rest.api.Constants;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -99,7 +100,16 @@ public class LoggingInterceptor implements IClientInterceptor {
public void interceptResponse(IHttpResponse theResponse) throws IOException { public void interceptResponse(IHttpResponse theResponse) throws IOException {
if (myLogResponseSummary) { if (myLogResponseSummary) {
String message = "HTTP " + theResponse.getStatus() + " " + theResponse.getStatusInfo(); String message = "HTTP " + theResponse.getStatus() + " " + theResponse.getStatusInfo();
myLog.info("Client response: {}", message); String respLocation = "";
/*
* Add response location
*/
List<String> locationHeaders = theResponse.getHeaders(Constants.HEADER_LOCATION);
if (locationHeaders != null && locationHeaders.size() > 0) {
respLocation = " (Location: " + locationHeaders.get(0) + ")";
}
myLog.info("Client response: {}{}", message, respLocation);
} }
if (myLogResponseHeaders) { if (myLogResponseHeaders) {

View File

@ -36,6 +36,7 @@ import org.apache.lucene.analysis.phonetic.PhoneticFilterFactory;
import org.apache.lucene.analysis.snowball.SnowballPorterFilterFactory; import org.apache.lucene.analysis.snowball.SnowballPorterFilterFactory;
import org.apache.lucene.analysis.standard.StandardFilterFactory; import org.apache.lucene.analysis.standard.StandardFilterFactory;
import org.apache.lucene.analysis.standard.StandardTokenizerFactory; import org.apache.lucene.analysis.standard.StandardTokenizerFactory;
import org.hibernate.annotations.ColumnDefault;
import org.hibernate.search.annotations.*; import org.hibernate.search.annotations.*;
import org.hibernate.search.annotations.Parameter; import org.hibernate.search.annotations.Parameter;
@ -204,8 +205,9 @@ public class ResourceTable extends BaseHasResource implements Serializable {
private String myProfile; private String myProfile;
@OneToMany(mappedBy = "myResource", cascade = {}, fetch = FetchType.LAZY, orphanRemoval = false) @OneToMany(mappedBy = "myResource", cascade = {}, fetch = FetchType.LAZY, orphanRemoval = false)
private Collection<ResourceIndexedCompositeStringUnique> myParamsCompositeStringUnique; private Collection<ResourceIndexedCompositeStringUnique> myParamsCompositeStringUnique;
// Added in 3.0.0 - Should make this a primitive Boolean at some point
@Column(name = "SP_CMPSTR_UNIQ_PRESENT") @Column(name = "SP_CMPSTR_UNIQ_PRESENT")
private boolean myParamsCompositeStringUniquePresent; private Boolean myParamsCompositeStringUniquePresent = false;
@OneToMany(mappedBy = "mySourceResource", cascade = {}, fetch = FetchType.LAZY, orphanRemoval = false) @OneToMany(mappedBy = "mySourceResource", cascade = {}, fetch = FetchType.LAZY, orphanRemoval = false)
@IndexedEmbedded() @IndexedEmbedded()
private Collection<ResourceLink> myResourceLinks; private Collection<ResourceLink> myResourceLinks;
@ -456,6 +458,9 @@ public class ResourceTable extends BaseHasResource implements Serializable {
} }
public boolean isParamsCompositeStringUniquePresent() { public boolean isParamsCompositeStringUniquePresent() {
if (myParamsCompositeStringUniquePresent == null) {
return false;
}
return myParamsCompositeStringUniquePresent; return myParamsCompositeStringUniquePresent;
} }

View File

@ -66,7 +66,32 @@ public class LoggingInterceptorTest {
} }
@Test @Test
public void testLogger() throws Exception { public void testLoggerNonVerbose() throws Exception {
System.out.println("Starting testLogger");
IGenericClient client = ourCtx.newRestfulGenericClient("http://localhost:" + ourPort);
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
LoggingInterceptor interceptor = new LoggingInterceptor(false);
client.registerInterceptor(interceptor);
Patient patient = client.read(Patient.class, "1");
assertFalse(patient.getIdentifierFirstRep().isEmpty());
verify(myMockAppender, times(2)).doAppend(argThat(new ArgumentMatcher<ILoggingEvent>() {
@Override
public boolean matches(final Object argument) {
String formattedMessage = ((LoggingEvent) argument).getFormattedMessage();
System.out.flush();
System.out.println("** Got Message: " + formattedMessage);
System.out.flush();
return
formattedMessage.contains("Client request: GET http://localhost:" + ourPort + "/Patient/1 HTTP/1.1") ||
formattedMessage.contains("Client response: HTTP 200 OK (Location: http://localhost:" + ourPort + "/Patient/1/_history/1)");
}
}));
}
@Test
public void testLoggerVerbose() throws Exception {
System.out.println("Starting testLogger"); System.out.println("Starting testLogger");
IGenericClient client = ourCtx.newRestfulGenericClient("http://localhost:" + ourPort); IGenericClient client = ourCtx.newRestfulGenericClient("http://localhost:" + ourPort);
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER); ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);

View File

@ -355,6 +355,12 @@
so that a database constraint will prevent more than one resource from so that a database constraint will prevent more than one resource from
having a matching pair having a matching pair
</action> </action>
<action type="add">
When using the client LoggingInterceptor in non-verbose mode, the
log line showing the server's response HTTP status will now also include
the returned
<![CDATA[<code>Location</code>]]> header value as well
</action>
</release> </release>
<release version="2.5" date="2017-06-08"> <release version="2.5" date="2017-06-08">
<action type="fix"> <action type="fix">