Allow fluent client to handle return types other than Parameters when
invoking operations
This commit is contained in:
parent
5384af1004
commit
2c4139dc82
|
@ -10,7 +10,7 @@ package ca.uhn.fhir.rest.client;
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -243,7 +243,8 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
return delete(theType, new IdDt(theId));
|
return delete(theType, new IdDt(theId));
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T extends IBaseResource> T doReadOrVRead(final Class<T> theType, IIdType theId, boolean theVRead, ICallable<T> theNotModifiedHandler, String theIfVersionMatches, Boolean thePrettyPrint, SummaryEnum theSummary, EncodingEnum theEncoding, Set<String> theSubsetElements) {
|
private <T extends IBaseResource> T doReadOrVRead(final Class<T> theType, IIdType theId, boolean theVRead, ICallable<T> theNotModifiedHandler, String theIfVersionMatches, Boolean thePrettyPrint,
|
||||||
|
SummaryEnum theSummary, EncodingEnum theEncoding, Set<String> theSubsetElements) {
|
||||||
String resName = toResourceName(theType);
|
String resName = toResourceName(theType);
|
||||||
IIdType id = theId;
|
IIdType id = theId;
|
||||||
if (!id.hasBaseUrl()) {
|
if (!id.hasBaseUrl()) {
|
||||||
|
@ -394,8 +395,8 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Use {@link LoggingInterceptor} as a client interceptor registered to your
|
* @deprecated Use {@link LoggingInterceptor} as a client interceptor registered to your
|
||||||
* client instead, as this provides much more fine-grained control over what is logged. This
|
* client instead, as this provides much more fine-grained control over what is logged. This
|
||||||
* method will be removed at some point (deprecated in HAPI 1.6 - 2016-06-16)
|
* method will be removed at some point (deprecated in HAPI 1.6 - 2016-06-16)
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public boolean isLogRequestAndResponse() {
|
public boolean isLogRequestAndResponse() {
|
||||||
|
@ -526,7 +527,6 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
return new ArrayList<IBaseResource>(resp.toListOfResources());
|
return new ArrayList<IBaseResource>(resp.toListOfResources());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IPatch patch() {
|
public IPatch patch() {
|
||||||
return new PatchInternal();
|
return new PatchInternal();
|
||||||
|
@ -1483,6 +1483,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
private RuntimeResourceDefinition myParametersDef;
|
private RuntimeResourceDefinition myParametersDef;
|
||||||
private Class<? extends IBaseResource> myType;
|
private Class<? extends IBaseResource> myType;
|
||||||
private boolean myUseHttpGet;
|
private boolean myUseHttpGet;
|
||||||
|
private Class myReturnResourceType;
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void addParam(String theName, IBase theValue) {
|
private void addParam(String theName, IBase theValue) {
|
||||||
|
@ -1552,25 +1553,33 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
|
|
||||||
BaseHttpClientInvocation invocation = OperationMethodBinding.createOperationInvocation(myContext, resourceName, id, myOperationName, myParameters, myUseHttpGet);
|
BaseHttpClientInvocation invocation = OperationMethodBinding.createOperationInvocation(myContext, resourceName, id, myOperationName, myParameters, myUseHttpGet);
|
||||||
|
|
||||||
ResourceResponseHandler handler = new ResourceResponseHandler();
|
if (myReturnResourceType != null) {
|
||||||
handler.setPreferResponseTypes(getPreferResponseTypes(myType));
|
ResourceResponseHandler handler;
|
||||||
|
handler = new ResourceResponseHandler(myReturnResourceType);
|
||||||
Object retVal = invoke(null, handler, invocation);
|
Object retVal = invoke(null, handler, invocation);
|
||||||
if (myContext.getResourceDefinition((IBaseResource) retVal).getName().equals("Parameters")) {
|
|
||||||
return retVal;
|
return retVal;
|
||||||
} else {
|
} else {
|
||||||
RuntimeResourceDefinition def = myContext.getResourceDefinition("Parameters");
|
ResourceResponseHandler handler;
|
||||||
IBaseResource parameters = def.newInstance();
|
handler = new ResourceResponseHandler();
|
||||||
|
handler.setPreferResponseTypes(getPreferResponseTypes(myType));
|
||||||
|
|
||||||
BaseRuntimeChildDefinition paramChild = def.getChildByName("parameter");
|
Object retVal = invoke(null, handler, invocation);
|
||||||
BaseRuntimeElementCompositeDefinition<?> paramChildElem = (BaseRuntimeElementCompositeDefinition<?>) paramChild.getChildByName("parameter");
|
if (myContext.getResourceDefinition((IBaseResource) retVal).getName().equals("Parameters")) {
|
||||||
IBase parameter = paramChildElem.newInstance();
|
return retVal;
|
||||||
paramChild.getMutator().addValue(parameters, parameter);
|
} else {
|
||||||
|
RuntimeResourceDefinition def = myContext.getResourceDefinition("Parameters");
|
||||||
|
IBaseResource parameters = def.newInstance();
|
||||||
|
|
||||||
BaseRuntimeChildDefinition resourceElem = paramChildElem.getChildByName("resource");
|
BaseRuntimeChildDefinition paramChild = def.getChildByName("parameter");
|
||||||
resourceElem.getMutator().addValue(parameter, (IBase) retVal);
|
BaseRuntimeElementCompositeDefinition<?> paramChildElem = (BaseRuntimeElementCompositeDefinition<?>) paramChild.getChildByName("parameter");
|
||||||
|
IBase parameter = paramChildElem.newInstance();
|
||||||
|
paramChild.getMutator().addValue(parameters, parameter);
|
||||||
|
|
||||||
return parameters;
|
BaseRuntimeChildDefinition resourceElem = paramChildElem.getChildByName("resource");
|
||||||
|
resourceElem.getMutator().addValue(parameter, (IBase) retVal);
|
||||||
|
|
||||||
|
return parameters;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1613,7 +1622,8 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
throw new IllegalArgumentException("theOutputParameterType must refer to a HAPI FHIR Resource type: " + theOutputParameterType.getName());
|
throw new IllegalArgumentException("theOutputParameterType must refer to a HAPI FHIR Resource type: " + theOutputParameterType.getName());
|
||||||
}
|
}
|
||||||
if (!"Parameters".equals(def.getName())) {
|
if (!"Parameters".equals(def.getName())) {
|
||||||
throw new IllegalArgumentException("theOutputParameterType must refer to a HAPI FHIR Resource type for a resource named " + "Parameters" + " - " + theOutputParameterType.getName() + " is a resource named: " + def.getName());
|
throw new IllegalArgumentException("theOutputParameterType must refer to a HAPI FHIR Resource type for a resource named " + "Parameters" + " - " + theOutputParameterType.getName()
|
||||||
|
+ " is a resource named: " + def.getName());
|
||||||
}
|
}
|
||||||
myParameters = (IBaseParameters) def.newInstance();
|
myParameters = (IBaseParameters) def.newInstance();
|
||||||
return this;
|
return this;
|
||||||
|
@ -1657,12 +1667,21 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IOperationUntypedWithInput returnResourceType(Class theReturnType) {
|
||||||
|
Validate.notNull(theReturnType, "theReturnType must not be null");
|
||||||
|
Validate.isTrue(IBaseResource.class.isAssignableFrom(theReturnType), "theReturnType must be a class which extends from IBaseResource");
|
||||||
|
myReturnResourceType = theReturnType;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class OperationOutcomeResponseHandler implements IClientResponseHandler<IBaseOperationOutcome> {
|
private final class OperationOutcomeResponseHandler implements IClientResponseHandler<IBaseOperationOutcome> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBaseOperationOutcome invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws BaseServerResponseException {
|
public IBaseOperationOutcome invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders)
|
||||||
|
throws BaseServerResponseException {
|
||||||
EncodingEnum respType = EncodingEnum.forContentType(theResponseMimeType);
|
EncodingEnum respType = EncodingEnum.forContentType(theResponseMimeType);
|
||||||
if (respType == null) {
|
if (respType == null) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -1858,7 +1877,8 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public List<IBaseResource> invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws BaseServerResponseException {
|
public List<IBaseResource> invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders)
|
||||||
|
throws BaseServerResponseException {
|
||||||
if (myContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU1)) {
|
if (myContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU1)) {
|
||||||
Class<? extends IBaseResource> bundleType = myContext.getResourceDefinition("Bundle").getImplementingClass();
|
Class<? extends IBaseResource> bundleType = myContext.getResourceDefinition("Bundle").getImplementingClass();
|
||||||
ResourceResponseHandler<IBaseResource> handler = new ResourceResponseHandler<IBaseResource>((Class<IBaseResource>) bundleType);
|
ResourceResponseHandler<IBaseResource> handler = new ResourceResponseHandler<IBaseResource>((Class<IBaseResource>) bundleType);
|
||||||
|
@ -2011,7 +2031,8 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (myReturnBundleType == null && myContext.getVersion().getVersion().isRi()) {
|
if (myReturnBundleType == null && myContext.getVersion().getVersion().isRi()) {
|
||||||
throw new IllegalArgumentException("When using the client with HL7.org structures, you must specify " + "the bundle return type for the client by adding \".returnBundle(org.hl7.fhir.instance.model.Bundle.class)\" to your search method call before the \".execute()\" method");
|
throw new IllegalArgumentException("When using the client with HL7.org structures, you must specify "
|
||||||
|
+ "the bundle return type for the client by adding \".returnBundle(org.hl7.fhir.instance.model.Bundle.class)\" to your search method call before the \".execute()\" method");
|
||||||
}
|
}
|
||||||
|
|
||||||
IClientResponseHandler<? extends IBase> binding;
|
IClientResponseHandler<? extends IBase> binding;
|
||||||
|
@ -2212,7 +2233,8 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
private final class StringResponseHandler implements IClientResponseHandler<String> {
|
private final class StringResponseHandler implements IClientResponseHandler<String> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws IOException, BaseServerResponseException {
|
public String invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders)
|
||||||
|
throws IOException, BaseServerResponseException {
|
||||||
return IOUtils.toString(theResponseReader);
|
return IOUtils.toString(theResponseReader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2367,7 +2389,6 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
throw new InvalidRequestException("No patch body supplied, cannot invoke server");
|
throw new InvalidRequestException("No patch body supplied, cannot invoke server");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (myId == null) {
|
if (myId == null) {
|
||||||
myId = myResource.getIdElement();
|
myId = myResource.getIdElement();
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,17 @@ public interface IOperationUntyped {
|
||||||
* Use chained method calls to construct a Parameters input. This form is a convenience
|
* Use chained method calls to construct a Parameters input. This form is a convenience
|
||||||
* in order to allow simple method chaining to be used to build up a parameters
|
* in order to allow simple method chaining to be used to build up a parameters
|
||||||
* resource for the input of an operation without needing to manually construct one.
|
* resource for the input of an operation without needing to manually construct one.
|
||||||
|
* <p>
|
||||||
|
* A sample invocation of this class could look like:<br/>
|
||||||
|
* <pre>Bundle bundle = client.operation()
|
||||||
|
* .onInstance(new IdType("Patient/A161443"))
|
||||||
|
* .named("everything")
|
||||||
|
* .withParameter(Parameters.class, "_count", new IntegerType(50))
|
||||||
|
* .useHttpGet()
|
||||||
|
* .returnResourceType(Bundle.class)
|
||||||
|
* .execute();
|
||||||
|
* </pre>
|
||||||
|
* </p>
|
||||||
*
|
*
|
||||||
* @param theParameterType The type to use for the output parameters (this should be set to
|
* @param theParameterType The type to use for the output parameters (this should be set to
|
||||||
* <code>Parameters.class</code> drawn from the version of the FHIR structures you are using)
|
* <code>Parameters.class</code> drawn from the version of the FHIR structures you are using)
|
||||||
|
|
|
@ -1,28 +1,8 @@
|
||||||
package ca.uhn.fhir.rest.gclient;
|
package ca.uhn.fhir.rest.gclient;
|
||||||
|
|
||||||
/*
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
* #%L
|
|
||||||
* HAPI FHIR - Core Library
|
|
||||||
* %%
|
|
||||||
* Copyright (C) 2014 - 2016 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 org.hl7.fhir.instance.model.api.IBaseParameters;
|
public interface IOperationUntypedWithInput<T> extends IClientExecutable<IOperationUntypedWithInput<T>, T> {
|
||||||
|
|
||||||
public interface IOperationUntypedWithInput<T extends IBaseParameters> extends IClientExecutable<IOperationUntypedWithInput<T>, T> {
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The client should invoke this method using an HTTP GET instead of an HTTP POST. Note that
|
* The client should invoke this method using an HTTP GET instead of an HTTP POST. Note that
|
||||||
|
@ -35,4 +15,12 @@ public interface IOperationUntypedWithInput<T extends IBaseParameters> extends I
|
||||||
*/
|
*/
|
||||||
IOperationUntypedWithInput<T> useHttpGet();
|
IOperationUntypedWithInput<T> useHttpGet();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If this operation returns a single resource body as its return type instead of a <code>Parameters</code>
|
||||||
|
* resource, use this method to specify that resource type. This is useful for certain
|
||||||
|
* operations (e.g. <code>Patient/NNN/$everything</code>) which return a bundle instead of
|
||||||
|
* a Parameters resource.
|
||||||
|
*/
|
||||||
|
<R extends IBaseResource> IOperationUntypedWithInput<R> returnResourceType(Class<R> theReturnType);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,6 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Lazy;
|
|
||||||
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
|
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
|
||||||
import org.springframework.core.env.Environment;
|
import org.springframework.core.env.Environment;
|
||||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||||
|
@ -38,12 +37,8 @@ import org.springframework.scheduling.concurrent.ConcurrentTaskScheduler;
|
||||||
import org.springframework.scheduling.concurrent.ScheduledExecutorFactoryBean;
|
import org.springframework.scheduling.concurrent.ScheduledExecutorFactoryBean;
|
||||||
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
|
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
|
||||||
import ca.uhn.fhir.context.ParserOptions;
|
|
||||||
import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider;
|
import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider;
|
||||||
import ca.uhn.fhir.jpa.search.StaleSearchDeletingSvc;
|
import ca.uhn.fhir.jpa.search.StaleSearchDeletingSvc;
|
||||||
import ca.uhn.fhir.jpa.term.BaseHapiTerminologySvc;
|
|
||||||
import ca.uhn.fhir.jpa.term.IHapiTerminologySvc;
|
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableScheduling
|
@EnableScheduling
|
||||||
|
@ -64,11 +59,10 @@ public class BaseConfig implements SchedulingConfigurer {
|
||||||
|
|
||||||
@Bean(autowire = Autowire.BY_TYPE)
|
@Bean(autowire = Autowire.BY_TYPE)
|
||||||
public DatabaseBackedPagingProvider databaseBackedPagingProvider() {
|
public DatabaseBackedPagingProvider databaseBackedPagingProvider() {
|
||||||
return new DatabaseBackedPagingProvider(10);
|
DatabaseBackedPagingProvider retVal = new DatabaseBackedPagingProvider(10);
|
||||||
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Bean(autowire=Autowire.BY_TYPE)
|
@Bean(autowire=Autowire.BY_TYPE)
|
||||||
public StaleSearchDeletingSvc staleSearchDeletingSvc() {
|
public StaleSearchDeletingSvc staleSearchDeletingSvc() {
|
||||||
return new StaleSearchDeletingSvc();
|
return new StaleSearchDeletingSvc();
|
||||||
|
|
|
@ -6,6 +6,7 @@ import static org.hamcrest.Matchers.containsInRelativeOrder;
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.hamcrest.Matchers.empty;
|
import static org.hamcrest.Matchers.empty;
|
||||||
import static org.hamcrest.Matchers.endsWith;
|
import static org.hamcrest.Matchers.endsWith;
|
||||||
|
import static org.hamcrest.Matchers.hasItem;
|
||||||
import static org.hamcrest.Matchers.hasItems;
|
import static org.hamcrest.Matchers.hasItems;
|
||||||
import static org.hamcrest.Matchers.not;
|
import static org.hamcrest.Matchers.not;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
@ -25,6 +26,9 @@ import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.hibernate.boot.model.source.spi.IdentifierSourceSimple;
|
import org.hibernate.boot.model.source.spi.IdentifierSourceSimple;
|
||||||
import org.hl7.fhir.dstu3.model.*;
|
import org.hl7.fhir.dstu3.model.*;
|
||||||
|
import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent;
|
||||||
|
import org.hl7.fhir.dstu3.model.Bundle.BundleType;
|
||||||
|
import org.hl7.fhir.dstu3.model.Bundle.HTTPVerb;
|
||||||
import org.hl7.fhir.dstu3.model.ContactPoint.ContactPointSystem;
|
import org.hl7.fhir.dstu3.model.ContactPoint.ContactPointSystem;
|
||||||
import org.hl7.fhir.dstu3.model.Enumerations.AdministrativeGender;
|
import org.hl7.fhir.dstu3.model.Enumerations.AdministrativeGender;
|
||||||
import org.hl7.fhir.dstu3.model.Subscription.SubscriptionChannelType;
|
import org.hl7.fhir.dstu3.model.Subscription.SubscriptionChannelType;
|
||||||
|
@ -32,6 +36,7 @@ import org.hl7.fhir.dstu3.model.Subscription.SubscriptionStatus;
|
||||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
|
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -41,6 +46,7 @@ import org.springframework.transaction.support.TransactionTemplate;
|
||||||
|
|
||||||
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
|
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
|
||||||
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
|
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
|
||||||
|
import ca.uhn.fhir.jpa.dao.SearchParameterMap.EverythingModeEnum;
|
||||||
import ca.uhn.fhir.jpa.entity.*;
|
import ca.uhn.fhir.jpa.entity.*;
|
||||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||||
import ca.uhn.fhir.model.api.Include;
|
import ca.uhn.fhir.model.api.Include;
|
||||||
|
@ -122,6 +128,54 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
|
||||||
assertThat(ids, contains(moId.getValue()));
|
assertThat(ids, contains(moId.getValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Per message from David Hay on Skype
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testEverythingWithLargeSet() throws Exception {
|
||||||
|
String inputString = IOUtils.toString(getClass().getResourceAsStream("/david_big_bundle.json"), StandardCharsets.UTF_8);
|
||||||
|
Bundle inputBundle = myFhirCtx.newJsonParser().parseResource(Bundle.class, inputString);
|
||||||
|
inputBundle.setType(BundleType.TRANSACTION);
|
||||||
|
|
||||||
|
Set<String> allIds = new TreeSet<String>();
|
||||||
|
for (BundleEntryComponent nextEntry : inputBundle.getEntry()) {
|
||||||
|
nextEntry.getRequest().setMethod(HTTPVerb.PUT);
|
||||||
|
nextEntry.getRequest().setUrl(nextEntry.getResource().getId());
|
||||||
|
allIds.add(nextEntry.getResource().getIdElement().toUnqualifiedVersionless().getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
mySystemDao.transaction(mySrd, inputBundle);
|
||||||
|
|
||||||
|
SearchParameterMap map = new SearchParameterMap();
|
||||||
|
map.setEverythingMode(EverythingModeEnum.PATIENT_INSTANCE);
|
||||||
|
IPrimitiveType<Integer> count = new IntegerType(1000);
|
||||||
|
IBundleProvider everything = myPatientDao.patientInstanceEverything(mySrd.getServletRequest(), new IdType("Patient/A161443"), count, null, null, null, null, mySrd);
|
||||||
|
|
||||||
|
TreeSet<String> ids = new TreeSet<String>(toUnqualifiedVersionlessIdValues(everything));
|
||||||
|
assertThat(ids, hasItem("List/A161444"));
|
||||||
|
assertThat(ids, hasItem("List/A161468"));
|
||||||
|
assertThat(ids, hasItem("List/A161500"));
|
||||||
|
|
||||||
|
ourLog.info("Expected {} - {}", allIds.size(), allIds);
|
||||||
|
ourLog.info("Actual {} - {}", ids.size(), ids);
|
||||||
|
assertEquals(allIds, ids);
|
||||||
|
|
||||||
|
ids = new TreeSet<String>();
|
||||||
|
for (int i = 0; i < everything.size(); i++) {
|
||||||
|
for (IBaseResource next : everything.getResources(i, i+1)) {
|
||||||
|
ids.add(next.getIdElement().toUnqualifiedVersionless().getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertThat(ids, hasItem("List/A161444"));
|
||||||
|
assertThat(ids, hasItem("List/A161468"));
|
||||||
|
assertThat(ids, hasItem("List/A161500"));
|
||||||
|
|
||||||
|
ourLog.info("Expected {} - {}", allIds.size(), allIds);
|
||||||
|
ourLog.info("Actual {} - {}", ids.size(), ids);
|
||||||
|
assertEquals(allIds, ids);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCodeSearch() {
|
public void testCodeSearch() {
|
||||||
Subscription subs = new Subscription();
|
Subscription subs = new Subscription();
|
||||||
|
|
|
@ -7,6 +7,7 @@ import static org.hamcrest.Matchers.containsInRelativeOrder;
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.hamcrest.Matchers.empty;
|
import static org.hamcrest.Matchers.empty;
|
||||||
import static org.hamcrest.Matchers.greaterThan;
|
import static org.hamcrest.Matchers.greaterThan;
|
||||||
|
import static org.hamcrest.Matchers.hasItem;
|
||||||
import static org.hamcrest.Matchers.hasItems;
|
import static org.hamcrest.Matchers.hasItems;
|
||||||
import static org.hamcrest.Matchers.hasSize;
|
import static org.hamcrest.Matchers.hasSize;
|
||||||
import static org.hamcrest.Matchers.not;
|
import static org.hamcrest.Matchers.not;
|
||||||
|
@ -28,9 +29,7 @@ import java.net.Socket;
|
||||||
import java.net.SocketTimeoutException;
|
import java.net.SocketTimeoutException;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
@ -57,12 +56,15 @@ import org.hl7.fhir.dstu3.model.Subscription.SubscriptionStatus;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
|
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
|
||||||
|
import ca.uhn.fhir.jpa.dao.SearchParameterMap.EverythingModeEnum;
|
||||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||||
import ca.uhn.fhir.model.primitive.UriDt;
|
import ca.uhn.fhir.model.primitive.UriDt;
|
||||||
import ca.uhn.fhir.parser.IParser;
|
import ca.uhn.fhir.parser.IParser;
|
||||||
|
@ -73,6 +75,7 @@ import ca.uhn.fhir.rest.api.ValidationModeEnum;
|
||||||
import ca.uhn.fhir.rest.client.IGenericClient;
|
import ca.uhn.fhir.rest.client.IGenericClient;
|
||||||
import ca.uhn.fhir.rest.param.*;
|
import ca.uhn.fhir.rest.param.*;
|
||||||
import ca.uhn.fhir.rest.server.Constants;
|
import ca.uhn.fhir.rest.server.Constants;
|
||||||
|
import ca.uhn.fhir.rest.server.IBundleProvider;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
|
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException;
|
import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException;
|
||||||
|
@ -115,6 +118,62 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Per message from David Hay on Skype
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testEverythingWithLargeSet() throws Exception {
|
||||||
|
String inputString = IOUtils.toString(getClass().getResourceAsStream("/david_big_bundle.json"), StandardCharsets.UTF_8);
|
||||||
|
Bundle inputBundle = myFhirCtx.newJsonParser().parseResource(Bundle.class, inputString);
|
||||||
|
inputBundle.setType(BundleType.TRANSACTION);
|
||||||
|
|
||||||
|
Set<String> allIds = new TreeSet<String>();
|
||||||
|
for (BundleEntryComponent nextEntry : inputBundle.getEntry()) {
|
||||||
|
nextEntry.getRequest().setMethod(HTTPVerb.PUT);
|
||||||
|
nextEntry.getRequest().setUrl(nextEntry.getResource().getId());
|
||||||
|
allIds.add(nextEntry.getResource().getIdElement().toUnqualifiedVersionless().getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
mySystemDao.transaction(mySrd, inputBundle);
|
||||||
|
|
||||||
|
Bundle responseBundle = ourClient
|
||||||
|
.operation()
|
||||||
|
.onInstance(new IdType("Patient/A161443"))
|
||||||
|
.named("everything")
|
||||||
|
.withParameter(Parameters.class, "_count", new IntegerType(50))
|
||||||
|
.useHttpGet()
|
||||||
|
.returnResourceType(Bundle.class)
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
TreeSet<String> ids = new TreeSet<String>();
|
||||||
|
for (int i = 0; i < responseBundle.getEntry().size(); i++) {
|
||||||
|
for (BundleEntryComponent nextEntry : responseBundle.getEntry()) {
|
||||||
|
ids.add(nextEntry.getResource().getIdElement().toUnqualifiedVersionless().getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String nextUrl = responseBundle.getLink("next").getUrl();
|
||||||
|
responseBundle = ourClient.fetchResourceFromUrl(Bundle.class, nextUrl);
|
||||||
|
for (int i = 0; i < responseBundle.getEntry().size(); i++) {
|
||||||
|
for (BundleEntryComponent nextEntry : responseBundle.getEntry()) {
|
||||||
|
ids.add(nextEntry.getResource().getIdElement().toUnqualifiedVersionless().getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assertThat(ids, hasItem("List/A161444"));
|
||||||
|
assertThat(ids, hasItem("List/A161468"));
|
||||||
|
assertThat(ids, hasItem("List/A161500"));
|
||||||
|
|
||||||
|
assertEquals(null, responseBundle.getLink("next"));
|
||||||
|
|
||||||
|
ourLog.info("Expected {} - {}", allIds.size(), allIds);
|
||||||
|
ourLog.info("Actual {} - {}", ids.size(), ids);
|
||||||
|
assertEquals(allIds, ids);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See #411
|
* See #411
|
||||||
*
|
*
|
||||||
|
|
|
@ -251,7 +251,7 @@ public class SystemProviderDstu3Test extends BaseJpaDstu3Test {
|
||||||
HttpGet get = new HttpGet(ourServerBase);
|
HttpGet get = new HttpGet(ourServerBase);
|
||||||
// get.addHeader("Accept", "application/xml, text/html");
|
// get.addHeader("Accept", "application/xml, text/html");
|
||||||
CloseableHttpResponse http = ourHttpClient.execute(get);
|
CloseableHttpResponse http = ourHttpClient.execute(get);
|
||||||
assertThat(http.getFirstHeader("Content-Type").getValue(), containsString("application/json+fhir"));
|
assertThat(http.getFirstHeader("Content-Type").getValue(), containsString("application/fhir+json"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -19,6 +19,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||||
|
|
||||||
import ca.uhn.fhir.jpa.config.BaseJavaConfigDstu3;
|
import ca.uhn.fhir.jpa.config.BaseJavaConfigDstu3;
|
||||||
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
||||||
|
import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider;
|
||||||
import ca.uhn.fhir.jpa.util.SubscriptionsRequireManualActivationInterceptorDstu3;
|
import ca.uhn.fhir.jpa.util.SubscriptionsRequireManualActivationInterceptorDstu3;
|
||||||
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
||||||
import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor;
|
import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor;
|
||||||
|
@ -50,9 +51,20 @@ public class TestDstu3Config extends BaseJavaConfigDstu3 {
|
||||||
retVal.setAllowExternalReferences(true);
|
retVal.setAllowExternalReferences(true);
|
||||||
retVal.getTreatBaseUrlsAsLocal().add("http://fhirtest.uhn.ca/baseDstu3");
|
retVal.getTreatBaseUrlsAsLocal().add("http://fhirtest.uhn.ca/baseDstu3");
|
||||||
retVal.getTreatBaseUrlsAsLocal().add("https://fhirtest.uhn.ca/baseDstu3");
|
retVal.getTreatBaseUrlsAsLocal().add("https://fhirtest.uhn.ca/baseDstu3");
|
||||||
|
retVal.setHardSearchLimit(500);
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Bean(autowire = Autowire.BY_TYPE)
|
||||||
|
public DatabaseBackedPagingProvider databaseBackedPagingProvider() {
|
||||||
|
DatabaseBackedPagingProvider retVal = super.databaseBackedPagingProvider();
|
||||||
|
retVal.setDefaultPageSize(20);
|
||||||
|
retVal.setMaximumPageSize(500);
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public IServerInterceptor securityInterceptor() {
|
public IServerInterceptor securityInterceptor() {
|
||||||
return new PublicSecurityInterceptor();
|
return new PublicSecurityInterceptor();
|
||||||
|
|
|
@ -158,6 +158,10 @@
|
||||||
interceptors are accessing the parameters and there is are also
|
interceptors are accessing the parameters and there is are also
|
||||||
parameters on the URL. Thanks to Jim Steel for reporting!
|
parameters on the URL. Thanks to Jim Steel for reporting!
|
||||||
</action>
|
</action>
|
||||||
|
<action type="add">
|
||||||
|
Fluent client can now return types other than Parameters
|
||||||
|
when invoking operations.
|
||||||
|
</action>
|
||||||
</release>
|
</release>
|
||||||
<release version="2.0" date="2016-08-30">
|
<release version="2.0" date="2016-08-30">
|
||||||
<action type="fix">
|
<action type="fix">
|
||||||
|
|
Loading…
Reference in New Issue