Fix #168 - Client conformance check should use any registered client
interceptors
This commit is contained in:
parent
b68ce95b3f
commit
cb7d94841e
|
@ -153,10 +153,14 @@ public abstract class BaseClient implements IRestfulClient {
|
||||||
return invokeClient(theContext, binding, clientInvocation, null, null, theLogRequestAndResponse);
|
return invokeClient(theContext, binding, clientInvocation, null, null, theLogRequestAndResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void forceConformanceCheck() {
|
||||||
|
myFactory.validateServerBase(myUrlBase, myClient, this);
|
||||||
|
}
|
||||||
|
|
||||||
<T> T invokeClient(FhirContext theContext, IClientResponseHandler<T> binding, BaseHttpClientInvocation clientInvocation, EncodingEnum theEncoding, Boolean thePrettyPrint, boolean theLogRequestAndResponse) {
|
<T> T invokeClient(FhirContext theContext, IClientResponseHandler<T> binding, BaseHttpClientInvocation clientInvocation, EncodingEnum theEncoding, Boolean thePrettyPrint, boolean theLogRequestAndResponse) {
|
||||||
|
|
||||||
if (!myDontValidateConformance) {
|
if (!myDontValidateConformance) {
|
||||||
myFactory.validateServerBaseIfConfiguredToDoSo(myUrlBase, myClient);
|
myFactory.validateServerBaseIfConfiguredToDoSo(myUrlBase, myClient, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: handle non 2xx status codes by throwing the correct exception,
|
// TODO: handle non 2xx status codes by throwing the correct exception,
|
||||||
|
@ -441,4 +445,8 @@ public abstract class BaseClient implements IRestfulClient {
|
||||||
return reader;
|
return reader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<IClientInterceptor> getInterceptors() {
|
||||||
|
return Collections.unmodifiableList(myInterceptors);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -156,6 +156,11 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
return resp;
|
return resp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void forceConformanceCheck() {
|
||||||
|
super.forceConformanceCheck();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ICreate create() {
|
public ICreate create() {
|
||||||
return new CreateInternal();
|
return new CreateInternal();
|
||||||
|
|
|
@ -34,6 +34,8 @@ import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
import ca.uhn.fhir.model.primitive.UriDt;
|
import ca.uhn.fhir.model.primitive.UriDt;
|
||||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||||
import ca.uhn.fhir.rest.client.api.IRestfulClient;
|
import ca.uhn.fhir.rest.client.api.IRestfulClient;
|
||||||
|
import ca.uhn.fhir.rest.client.exceptions.FhirClientConnectionException;
|
||||||
|
import ca.uhn.fhir.rest.client.exceptions.FhirClientInnapropriateForServerException;
|
||||||
import ca.uhn.fhir.rest.gclient.ICreate;
|
import ca.uhn.fhir.rest.gclient.ICreate;
|
||||||
import ca.uhn.fhir.rest.gclient.IDelete;
|
import ca.uhn.fhir.rest.gclient.IDelete;
|
||||||
import ca.uhn.fhir.rest.gclient.IGetPage;
|
import ca.uhn.fhir.rest.gclient.IGetPage;
|
||||||
|
@ -100,6 +102,16 @@ public interface IGenericClient extends IRestfulClient {
|
||||||
@Deprecated
|
@Deprecated
|
||||||
MethodOutcome delete(Class<? extends IResource> theType, String theId);
|
MethodOutcome delete(Class<? extends IResource> theType, String theId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Force the client to fetch the server's conformance statement and validate that it is appropriate for this client.
|
||||||
|
*
|
||||||
|
* @throws FhirClientConnectionException
|
||||||
|
* if the conformance statement cannot be read, or if the client
|
||||||
|
* @throws FhirClientInnapropriateForServerException
|
||||||
|
* If the conformance statement indicates that the server is inappropriate for this client (e.g. it implements the wrong version of FHIR)
|
||||||
|
*/
|
||||||
|
void forceConformanceCheck() throws FhirClientConnectionException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fluent method for the "get tags" operation
|
* Fluent method for the "get tags" operation
|
||||||
*/
|
*/
|
||||||
|
@ -114,17 +126,15 @@ public interface IGenericClient extends IRestfulClient {
|
||||||
* Implementation of the "history instance" method.
|
* Implementation of the "history instance" method.
|
||||||
*
|
*
|
||||||
* @param theType
|
* @param theType
|
||||||
* The type of resource to return the history for, or
|
* The type of resource to return the history for, or <code>null</code> to search for history across all resources
|
||||||
* <code>null</code> to search for history across all resources
|
|
||||||
* @param theId
|
* @param theId
|
||||||
* The ID of the resource to return the history for, or <code>null</code> to search for all resource
|
* The ID of the resource to return the history for, or <code>null</code> to search for all resource instances. Note that if this param is not null, <code>theType</code> must also not
|
||||||
* instances. Note that if this param is not null, <code>theType</code> must also not be null
|
* be null
|
||||||
* @param theSince
|
* @param theSince
|
||||||
* If not null, request that the server only return resources updated since this time
|
* If not null, request that the server only return resources updated since this time
|
||||||
* @param theLimit
|
* @param theLimit
|
||||||
* If not null, request that the server return no more than this number of resources. Note that the
|
* If not null, request that the server return no more than this number of resources. Note that the server may return less even if more are available, but should not return more
|
||||||
* server may return less even if more are available, but should not return more according to the FHIR
|
* according to the FHIR specification.
|
||||||
* specification.
|
|
||||||
* @return A bundle containing returned resources
|
* @return A bundle containing returned resources
|
||||||
* @deprecated As of 0.9, use the fluent {@link #history()} method instead
|
* @deprecated As of 0.9, use the fluent {@link #history()} method instead
|
||||||
*/
|
*/
|
||||||
|
@ -135,31 +145,21 @@ public interface IGenericClient extends IRestfulClient {
|
||||||
* Implementation of the "history instance" method.
|
* Implementation of the "history instance" method.
|
||||||
*
|
*
|
||||||
* @param theType
|
* @param theType
|
||||||
* The type of resource to return the history for, or
|
* The type of resource to return the history for, or <code>null</code> to search for history across all resources
|
||||||
* <code>null</code> to search for history across all resources
|
|
||||||
* @param theId
|
* @param theId
|
||||||
* The ID of the resource to return the history for, or <code>null</code> to search for all resource
|
* The ID of the resource to return the history for, or <code>null</code> to search for all resource instances. Note that if this param is not null, <code>theType</code> must also not
|
||||||
* instances. Note that if this param is not null, <code>theType</code> must also not be null
|
* be null
|
||||||
* @param theSince
|
* @param theSince
|
||||||
* If not null, request that the server only return resources updated since this time
|
* If not null, request that the server only return resources updated since this time
|
||||||
* @param theLimit
|
* @param theLimit
|
||||||
* If not null, request that the server return no more than this number of resources. Note that the
|
* If not null, request that the server return no more than this number of resources. Note that the server may return less even if more are available, but should not return more
|
||||||
* server may return less even if more are available, but should not return more according to the FHIR
|
* according to the FHIR specification.
|
||||||
* specification.
|
|
||||||
* @return A bundle containing returned resources
|
* @return A bundle containing returned resources
|
||||||
* @deprecated As of 0.9, use the fluent {@link #history()} method instead
|
* @deprecated As of 0.9, use the fluent {@link #history()} method instead
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
<T extends IResource> Bundle history(Class<T> theType, String theId, DateTimeDt theSince, Integer theLimit);
|
<T extends IResource> Bundle history(Class<T> theType, String theId, DateTimeDt theSince, Integer theLimit);
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads the previous/next bundle of resources from a paged set, using the link specified in the "link type=next"
|
|
||||||
* tag within the atom bundle.
|
|
||||||
*
|
|
||||||
* @see Bundle#getLinkNext()
|
|
||||||
*/
|
|
||||||
IGetPage loadPage();
|
|
||||||
|
|
||||||
// /**
|
// /**
|
||||||
// * Implementation of the "instance read" method. This method will only ever do a "read" for the latest version of a
|
// * Implementation of the "instance read" method. This method will only ever do a "read" for the latest version of a
|
||||||
// * given resource instance, even if the ID passed in contains a version. If you wish to request a specific version
|
// * given resource instance, even if the ID passed in contains a version. If you wish to request a specific version
|
||||||
|
@ -178,6 +178,13 @@ public interface IGenericClient extends IRestfulClient {
|
||||||
// */
|
// */
|
||||||
// <T extends IBaseResource> T read(Class<T> theType, IdDt theId);
|
// <T extends IBaseResource> T read(Class<T> theType, IdDt theId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the previous/next bundle of resources from a paged set, using the link specified in the "link type=next" tag within the atom bundle.
|
||||||
|
*
|
||||||
|
* @see Bundle#getLinkNext()
|
||||||
|
*/
|
||||||
|
IGetPage loadPage();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of the FHIR "extended operations" action
|
* Implementation of the FHIR "extended operations" action
|
||||||
*/
|
*/
|
||||||
|
@ -220,8 +227,7 @@ public interface IGenericClient extends IRestfulClient {
|
||||||
IResource read(UriDt theUrl);
|
IResource read(UriDt theUrl);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a new interceptor for this client. An interceptor can be used to add additional logging, or add security
|
* Register a new interceptor for this client. An interceptor can be used to add additional logging, or add security headers, or pre-process responses, etc.
|
||||||
* headers, or pre-process responses, etc.
|
|
||||||
*/
|
*/
|
||||||
void registerInterceptor(IClientInterceptor theInterceptor);
|
void registerInterceptor(IClientInterceptor theInterceptor);
|
||||||
|
|
||||||
|
@ -250,8 +256,8 @@ public interface IGenericClient extends IRestfulClient {
|
||||||
Bundle search(UriDt theUrl);
|
Bundle search(UriDt theUrl);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If set to <code>true</code>, the client will log all requests and all responses. This is probably not a good
|
* If set to <code>true</code>, the client will log all requests and all responses. This is probably not a good production setting since it will result in a lot of extra logging, but it can be
|
||||||
* production setting since it will result in a lot of extra logging, but it can be useful for troubleshooting.
|
* useful for troubleshooting.
|
||||||
*
|
*
|
||||||
* @param theLogRequestAndResponse
|
* @param theLogRequestAndResponse
|
||||||
* Should requests and responses be logged
|
* Should requests and responses be logged
|
||||||
|
@ -268,8 +274,7 @@ public interface IGenericClient extends IRestfulClient {
|
||||||
*
|
*
|
||||||
* @param theResources
|
* @param theResources
|
||||||
* The resources to create/update in a single transaction
|
* The resources to create/update in a single transaction
|
||||||
* @return A list of resource stubs (<b>these will not be fully populated</b>) containing IDs and other
|
* @return A list of resource stubs (<b>these will not be fully populated</b>) containing IDs and other {@link IResource#getResourceMetadata() metadata}
|
||||||
* {@link IResource#getResourceMetadata() metadata}
|
|
||||||
* @deprecated Use {@link #transaction()}
|
* @deprecated Use {@link #transaction()}
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -277,8 +282,7 @@ public interface IGenericClient extends IRestfulClient {
|
||||||
List<IResource> transaction(List<IResource> theResources);
|
List<IResource> transaction(List<IResource> theResources);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove an intercaptor that was previously registered using
|
* Remove an intercaptor that was previously registered using {@link IRestfulClient#registerInterceptor(IClientInterceptor)}
|
||||||
* {@link IRestfulClient#registerInterceptor(IClientInterceptor)}
|
|
||||||
*/
|
*/
|
||||||
void unregisterInterceptor(IClientInterceptor theInterceptor);
|
void unregisterInterceptor(IClientInterceptor theInterceptor);
|
||||||
|
|
||||||
|
@ -319,18 +323,16 @@ public interface IGenericClient extends IRestfulClient {
|
||||||
MethodOutcome validate(IResource theResource);
|
MethodOutcome validate(IResource theResource);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of the "instance vread" method. Note that this method expects <code>theId</code> to contain a
|
* Implementation of the "instance vread" method. Note that this method expects <code>theId</code> to contain a resource ID as well as a version ID, and will fail if it does not.
|
||||||
* resource ID as well as a version ID, and will fail if it does not.
|
|
||||||
* <p>
|
* <p>
|
||||||
* Note that if an absolute resource ID is passed in (i.e. a URL containing a protocol and host as well as the
|
* Note that if an absolute resource ID is passed in (i.e. a URL containing a protocol and host as well as the resource type and ID) the server base for the client will be ignored, and the URL
|
||||||
* resource type and ID) the server base for the client will be ignored, and the URL passed in will be queried.
|
* passed in will be queried.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param theType
|
* @param theType
|
||||||
* The type of resource to load
|
* The type of resource to load
|
||||||
* @param theId
|
* @param theId
|
||||||
* The ID to load, including the resource ID and the resource version ID. Valid values include
|
* The ID to load, including the resource ID and the resource version ID. Valid values include "Patient/123/_history/222", or "http://example.com/fhir/Patient/123/_history/222"
|
||||||
* "Patient/123/_history/222", or "http://example.com/fhir/Patient/123/_history/222"
|
|
||||||
* @return The resource
|
* @return The resource
|
||||||
*/
|
*/
|
||||||
<T extends IBaseResource> T vread(Class<T> theType, IdDt theId);
|
<T extends IBaseResource> T vread(Class<T> theType, IdDt theId);
|
||||||
|
|
|
@ -50,6 +50,7 @@ import ca.uhn.fhir.context.FhirVersionEnum;
|
||||||
import ca.uhn.fhir.model.base.resource.BaseConformance;
|
import ca.uhn.fhir.model.base.resource.BaseConformance;
|
||||||
import ca.uhn.fhir.rest.client.api.IRestfulClient;
|
import ca.uhn.fhir.rest.client.api.IRestfulClient;
|
||||||
import ca.uhn.fhir.rest.client.exceptions.FhirClientConnectionException;
|
import ca.uhn.fhir.rest.client.exceptions.FhirClientConnectionException;
|
||||||
|
import ca.uhn.fhir.rest.client.exceptions.FhirClientInnapropriateForServerException;
|
||||||
import ca.uhn.fhir.rest.method.BaseMethodBinding;
|
import ca.uhn.fhir.rest.method.BaseMethodBinding;
|
||||||
import ca.uhn.fhir.rest.server.Constants;
|
import ca.uhn.fhir.rest.server.Constants;
|
||||||
|
|
||||||
|
@ -193,25 +194,29 @@ public class RestfulClientFactory implements IRestfulClientFactory {
|
||||||
/**
|
/**
|
||||||
* This method is internal to HAPI - It may change in future versions, use with caution.
|
* This method is internal to HAPI - It may change in future versions, use with caution.
|
||||||
*/
|
*/
|
||||||
public void validateServerBaseIfConfiguredToDoSo(String theServerBase, HttpClient theHttpClient) {
|
public void validateServerBaseIfConfiguredToDoSo(String theServerBase, HttpClient theHttpClient, BaseClient theClient) {
|
||||||
String serverBase = theServerBase;
|
String serverBase = normalizeBaseUrlForMap(theServerBase);
|
||||||
if (!serverBase.endsWith("/")) {
|
|
||||||
serverBase = serverBase + "/";
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (myServerValidationMode) {
|
switch (myServerValidationMode) {
|
||||||
case NEVER:
|
case NEVER:
|
||||||
break;
|
break;
|
||||||
case ONCE:
|
case ONCE:
|
||||||
if (!myValidatedServerBaseUrls.contains(serverBase)) {
|
if (!myValidatedServerBaseUrls.contains(serverBase)) {
|
||||||
validateServerBase(serverBase, theHttpClient);
|
validateServerBase(serverBase, theHttpClient, theClient);
|
||||||
myValidatedServerBaseUrls.add(serverBase);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String normalizeBaseUrlForMap(String theServerBase) {
|
||||||
|
String serverBase = theServerBase;
|
||||||
|
if (!serverBase.endsWith("/")) {
|
||||||
|
serverBase = serverBase + "/";
|
||||||
|
}
|
||||||
|
return serverBase;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void setConnectionRequestTimeout(int theConnectionRequestTimeout) {
|
public synchronized void setConnectionRequestTimeout(int theConnectionRequestTimeout) {
|
||||||
myConnectionRequestTimeout = theConnectionRequestTimeout;
|
myConnectionRequestTimeout = theConnectionRequestTimeout;
|
||||||
|
@ -267,9 +272,12 @@ public class RestfulClientFactory implements IRestfulClientFactory {
|
||||||
myHttpClient = null;
|
myHttpClient = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateServerBase(String theServerBase, HttpClient theHttpClient) {
|
void validateServerBase(String theServerBase, HttpClient theHttpClient, BaseClient theClient) {
|
||||||
|
|
||||||
GenericClient client = new GenericClient(myContext, theHttpClient, theServerBase, this);
|
GenericClient client = new GenericClient(myContext, theHttpClient, theServerBase, this);
|
||||||
|
for (IClientInterceptor interceptor : theClient.getInterceptors()) {
|
||||||
|
client.registerInterceptor(interceptor);
|
||||||
|
}
|
||||||
client.setDontValidateConformance(true);
|
client.setDontValidateConformance(true);
|
||||||
|
|
||||||
BaseConformance conformance;
|
BaseConformance conformance;
|
||||||
|
@ -299,9 +307,12 @@ public class RestfulClientFactory implements IRestfulClientFactory {
|
||||||
if (serverFhirVersionEnum != null) {
|
if (serverFhirVersionEnum != null) {
|
||||||
FhirVersionEnum contextFhirVersion = myContext.getVersion().getVersion();
|
FhirVersionEnum contextFhirVersion = myContext.getVersion().getVersion();
|
||||||
if (!contextFhirVersion.isEquivalentTo(serverFhirVersionEnum)) {
|
if (!contextFhirVersion.isEquivalentTo(serverFhirVersionEnum)) {
|
||||||
throw new FhirClientConnectionException(myContext.getLocalizer().getMessage(RestfulClientFactory.class, "wrongVersionInConformance", theServerBase + Constants.URL_TOKEN_METADATA, serverFhirVersionString, serverFhirVersionEnum, contextFhirVersion));
|
throw new FhirClientInnapropriateForServerException(myContext.getLocalizer().getMessage(RestfulClientFactory.class, "wrongVersionInConformance", theServerBase + Constants.URL_TOKEN_METADATA, serverFhirVersionString, serverFhirVersionEnum, contextFhirVersion));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
myValidatedServerBaseUrls.add(normalizeBaseUrlForMap(theServerBase));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
package ca.uhn.fhir.rest.client.exceptions;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* HAPI FHIR - Core Library
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2014 - 2015 University Health Network
|
||||||
|
* %%
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
|
||||||
|
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This exception will be thrown by FHIR clients if the client attempts to
|
||||||
|
* communicate with a server which is a valid FHIR server but is incompatible
|
||||||
|
* with this client for some reason.
|
||||||
|
*/
|
||||||
|
public class FhirClientInnapropriateForServerException extends BaseServerResponseException {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public FhirClientInnapropriateForServerException(Throwable theCause) {
|
||||||
|
super(0, theCause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FhirClientInnapropriateForServerException(String theMessage, Throwable theCause) {
|
||||||
|
super(0, theMessage, theCause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FhirClientInnapropriateForServerException(String theMessage) {
|
||||||
|
super(0, theMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -198,4 +198,52 @@ public class ClientServerValidationTestDstu2 {
|
||||||
assertEquals("Basic VVNFUjpQQVNT", auth.getValue());
|
assertEquals("Basic VVNFUjpQQVNT", auth.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testForceConformanceCheck() throws Exception {
|
||||||
|
Conformance conf = new Conformance();
|
||||||
|
conf.setFhirVersion("0.5.0");
|
||||||
|
final String confResource = myCtx.newXmlParser().encodeResourceToString(conf);
|
||||||
|
|
||||||
|
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||||
|
|
||||||
|
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()).thenAnswer(new Answer<InputStream>() {
|
||||||
|
@Override
|
||||||
|
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||||
|
if (myFirstResponse) {
|
||||||
|
myFirstResponse = false;
|
||||||
|
return new ReaderInputStream(new StringReader(confResource), Charset.forName("UTF-8"));
|
||||||
|
} else {
|
||||||
|
Patient resource = new Patient();
|
||||||
|
resource.addName().addFamily().setValue("FAM");
|
||||||
|
return new ReaderInputStream(new StringReader(myCtx.newXmlParser().encodeResourceToString(resource)), Charset.forName("UTF-8"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||||
|
|
||||||
|
myCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.ONCE);
|
||||||
|
|
||||||
|
IGenericClient client = myCtx.newRestfulGenericClient("http://foo");
|
||||||
|
client.registerInterceptor(new BasicAuthInterceptor("USER", "PASS"));
|
||||||
|
|
||||||
|
client.forceConformanceCheck();
|
||||||
|
|
||||||
|
assertEquals(1, capt.getAllValues().size());
|
||||||
|
|
||||||
|
Patient pt = (Patient) client.read(new UriDt("http://foo/Patient/123"));
|
||||||
|
assertEquals("FAM", pt.getNameFirstRep().getFamilyAsSingleString());
|
||||||
|
|
||||||
|
assertEquals(2, capt.getAllValues().size());
|
||||||
|
|
||||||
|
Header auth = capt.getAllValues().get(0).getFirstHeader("Authorization");
|
||||||
|
assertNotNull(auth);
|
||||||
|
assertEquals("Basic VVNFUjpQQVNT", auth.getValue());
|
||||||
|
auth = capt.getAllValues().get(1).getFirstHeader("Authorization");
|
||||||
|
assertNotNull(auth);
|
||||||
|
assertEquals("Basic VVNFUjpQQVNT", auth.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir</artifactId>
|
<artifactId>hapi-fhir</artifactId>
|
||||||
<version>0.9-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-base</artifactId>
|
<artifactId>hapi-fhir-base</artifactId>
|
||||||
<version>0.9-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.thymeleaf</groupId>
|
<groupId>org.thymeleaf</groupId>
|
||||||
|
@ -38,7 +38,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javax.servlet</groupId>
|
<groupId>javax.servlet</groupId>
|
||||||
<artifactId>javax.servlet-api</artifactId>
|
<artifactId>javax.servlet-api</artifactId>
|
||||||
<version>3.1.0</version>
|
<version>${servlet_api_version}</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|
|
@ -168,6 +168,15 @@
|
||||||
Make BaseElement#getUndeclaredExtensions() and BaseElement#getUndeclaredExtensions() return
|
Make BaseElement#getUndeclaredExtensions() and BaseElement#getUndeclaredExtensions() return
|
||||||
a mutable list so that it is possible to delete extensions from a resource instance.
|
a mutable list so that it is possible to delete extensions from a resource instance.
|
||||||
</action>
|
</action>
|
||||||
|
<action type="fix" issue="168">
|
||||||
|
Server conformance statement check in clients (this is the check
|
||||||
|
where the first time a given FhirContext is used to access a given server
|
||||||
|
base URL, it will first check the server's Conformance statement to ensure
|
||||||
|
that it supports the correct version of FHIR) now uses any
|
||||||
|
registered client interceptors. In addition, IGenericClient now has a method
|
||||||
|
"forceConformanceCheck()" which manually triggers this check. Thanks to
|
||||||
|
Doug Martin for reporting and suggesting!
|
||||||
|
</action>
|
||||||
</release>
|
</release>
|
||||||
<release version="0.9" date="2015-Mar-14">
|
<release version="0.9" date="2015-Mar-14">
|
||||||
<action type="add">
|
<action type="add">
|
||||||
|
|
Loading…
Reference in New Issue