Fix #1163 - Correctly handle invalid CapabilityStatement
This commit is contained in:
parent
dec53c1eea
commit
fc09ed6966
|
@ -301,7 +301,7 @@ public abstract class RestfulClientFactory implements IRestfulClientFactory {
|
||||||
conformance = (IBaseResource) client.fetchConformance().ofType(implementingClass).execute();
|
conformance = (IBaseResource) client.fetchConformance().ofType(implementingClass).execute();
|
||||||
} catch (FhirClientConnectionException e) {
|
} catch (FhirClientConnectionException e) {
|
||||||
if (!myContext.getVersion().getVersion().isOlderThan(FhirVersionEnum.DSTU3) && e.getCause() instanceof DataFormatException) {
|
if (!myContext.getVersion().getVersion().isOlderThan(FhirVersionEnum.DSTU3) && e.getCause() instanceof DataFormatException) {
|
||||||
capabilityStatementResourceName = "Conformance";
|
capabilityStatementResourceName = "CapabilityStatement";
|
||||||
implementingClass = myContext.getResourceDefinition(capabilityStatementResourceName).getImplementingClass();
|
implementingClass = myContext.getResourceDefinition(capabilityStatementResourceName).getImplementingClass();
|
||||||
conformance = (IBaseResource) client.fetchConformance().ofType(implementingClass).execute();
|
conformance = (IBaseResource) client.fetchConformance().ofType(implementingClass).execute();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -10,7 +10,9 @@ import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||||
import ca.uhn.fhir.rest.api.SummaryEnum;
|
import ca.uhn.fhir.rest.api.SummaryEnum;
|
||||||
import ca.uhn.fhir.rest.client.apache.ApacheHttpRequest;
|
import ca.uhn.fhir.rest.client.apache.ApacheHttpRequest;
|
||||||
import ca.uhn.fhir.rest.client.api.IBasicClient;
|
import ca.uhn.fhir.rest.client.api.IBasicClient;
|
||||||
|
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
||||||
import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum;
|
import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum;
|
||||||
|
import ca.uhn.fhir.rest.client.exceptions.FhirClientConnectionException;
|
||||||
import ca.uhn.fhir.rest.client.interceptor.CapturingInterceptor;
|
import ca.uhn.fhir.rest.client.interceptor.CapturingInterceptor;
|
||||||
import ca.uhn.fhir.rest.param.*;
|
import ca.uhn.fhir.rest.param.*;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||||
|
@ -57,8 +59,8 @@ import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
public class ClientR4Test {
|
public class ClientR4Test {
|
||||||
|
|
||||||
private static FhirContext ourCtx = FhirContext.forR4();
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ClientR4Test.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ClientR4Test.class);
|
||||||
|
private static FhirContext ourCtx = FhirContext.forR4();
|
||||||
private HttpClient myHttpClient;
|
private HttpClient myHttpClient;
|
||||||
|
|
||||||
private HttpResponse myHttpResponse;
|
private HttpResponse myHttpResponse;
|
||||||
|
@ -959,7 +961,6 @@ public class ClientR4Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSearchWithStringIncludes() throws Exception {
|
public void testSearchWithStringIncludes() throws Exception {
|
||||||
|
|
||||||
|
@ -1142,6 +1143,29 @@ public class ClientR4Test {
|
||||||
assertNull(response.getResource());
|
assertNull(response.getResource());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidateServerBaseWithInvalidResponse() throws Exception {
|
||||||
|
|
||||||
|
String response = "AAAAAAA";
|
||||||
|
|
||||||
|
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||||
|
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||||
|
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||||
|
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||||
|
when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(response), Charset.forName("UTF-8")));
|
||||||
|
|
||||||
|
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.ONCE);
|
||||||
|
IGenericClient client = ourCtx.newRestfulGenericClient("http://testValidateServerBaseWithInvalidResponse");
|
||||||
|
try {
|
||||||
|
client.read().resource("Patient").withId("1").execute();
|
||||||
|
fail();
|
||||||
|
} catch (FhirClientConnectionException e) {
|
||||||
|
assertEquals("Failed to retrieve the server metadata statement during client initialization. URL used was http://testValidateServerBaseWithInvalidResponse/metadata", e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testValidateOutcomeResponse() throws Exception {
|
public void testValidateOutcomeResponse() throws Exception {
|
||||||
|
|
||||||
|
@ -1221,6 +1245,51 @@ public class ClientR4Test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private interface ClientWithoutAnnotation extends IBasicClient {
|
||||||
|
Patient read(@IdParam IdType theId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ITestClientWithCustomType extends IBasicClient {
|
||||||
|
@Search()
|
||||||
|
public CustomPatient getPatientByDob(@RequiredParam(name = Patient.SP_BIRTHDATE) DateParam theBirthDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ITestClientWithCustomTypeList extends IBasicClient {
|
||||||
|
@Search()
|
||||||
|
public List<CustomPatient> getPatientByDob(@RequiredParam(name = Patient.SP_BIRTHDATE) DateParam theBirthDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ITestClientWithElements extends IBasicClient {
|
||||||
|
@Search()
|
||||||
|
public List<Patient> getPatientWithIncludes(@Elements Set<String> theElements);
|
||||||
|
|
||||||
|
@Search()
|
||||||
|
public List<Patient> getPatientWithIncludes(@Elements String theElements);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ITestClientWithStringIncludes extends IBasicClient {
|
||||||
|
@Search()
|
||||||
|
public Patient getPatientWithIncludes(@RequiredParam(name = "withIncludes") StringParam theString, @IncludeParam String theInclude);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ITestClientWithSummary extends IBasicClient {
|
||||||
|
@Search()
|
||||||
|
public List<Patient> getPatientWithIncludes(List<SummaryEnum> theSummary);
|
||||||
|
|
||||||
|
@Search()
|
||||||
|
public List<Patient> getPatientWithIncludes(SummaryEnum theSummary);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@ResourceDef(name = "Patient")
|
||||||
|
public static class CustomPatient extends Patient {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
// nothing
|
||||||
|
}
|
||||||
|
|
||||||
@AfterClass
|
@AfterClass
|
||||||
public static void afterClassClearContext() {
|
public static void afterClassClearContext() {
|
||||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||||
|
@ -1265,49 +1334,4 @@ public class ClientR4Test {
|
||||||
// return msg;
|
// return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
private interface ClientWithoutAnnotation extends IBasicClient {
|
|
||||||
Patient read(@IdParam IdType theId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ResourceDef(name = "Patient")
|
|
||||||
public static class CustomPatient extends Patient {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
// nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface ITestClientWithCustomType extends IBasicClient {
|
|
||||||
@Search()
|
|
||||||
public CustomPatient getPatientByDob(@RequiredParam(name = Patient.SP_BIRTHDATE) DateParam theBirthDate);
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface ITestClientWithCustomTypeList extends IBasicClient {
|
|
||||||
@Search()
|
|
||||||
public List<CustomPatient> getPatientByDob(@RequiredParam(name = Patient.SP_BIRTHDATE) DateParam theBirthDate);
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface ITestClientWithElements extends IBasicClient {
|
|
||||||
@Search()
|
|
||||||
public List<Patient> getPatientWithIncludes(@Elements Set<String> theElements);
|
|
||||||
|
|
||||||
@Search()
|
|
||||||
public List<Patient> getPatientWithIncludes(@Elements String theElements);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface ITestClientWithStringIncludes extends IBasicClient {
|
|
||||||
@Search()
|
|
||||||
public Patient getPatientWithIncludes(@RequiredParam(name = "withIncludes") StringParam theString, @IncludeParam String theInclude);
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface ITestClientWithSummary extends IBasicClient {
|
|
||||||
@Search()
|
|
||||||
public List<Patient> getPatientWithIncludes(List<SummaryEnum> theSummary);
|
|
||||||
|
|
||||||
@Search()
|
|
||||||
public List<Patient> getPatientWithIncludes(SummaryEnum theSummary);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -283,6 +283,12 @@
|
||||||
AuthorizationInterceptor could not authorize these requests if it was depending on
|
AuthorizationInterceptor could not authorize these requests if it was depending on
|
||||||
headers being present.
|
headers being present.
|
||||||
</action>
|
</action>
|
||||||
|
<action type="fix">
|
||||||
|
When using a client in DSTU3/R4 mode, if the client attempted to validate the server
|
||||||
|
CapabilityStatement but was not able to parse the response, the client would throw
|
||||||
|
an exception with a misleading error about the Conformance resource not existing. This
|
||||||
|
has been corrected. Thanks to Shayaan Munshi for reporting and providing a test case!
|
||||||
|
</action>
|
||||||
</release>
|
</release>
|
||||||
<release version="3.6.0" date="2018-11-12" description="Food">
|
<release version="3.6.0" date="2018-11-12" description="Food">
|
||||||
<action type="add">
|
<action type="add">
|
||||||
|
|
Loading…
Reference in New Issue