Merge branch 'master' into documentOperation

This commit is contained in:
patrick-werner 2018-06-07 09:17:58 +02:00
commit 6bcddea416
13 changed files with 124 additions and 85 deletions

View File

@ -58,6 +58,7 @@ import ca.uhn.fhir.util.*;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Charsets; import com.google.common.base.Charsets;
import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.google.common.hash.HashFunction; import com.google.common.hash.HashFunction;
import com.google.common.hash.Hashing; import com.google.common.hash.Hashing;
@ -85,6 +86,7 @@ import org.springframework.stereotype.Repository;
import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.support.TransactionTemplate; import org.springframework.transaction.support.TransactionTemplate;
import javax.annotation.PostConstruct;
import javax.persistence.*; import javax.persistence.*;
import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.CriteriaQuery;
@ -727,23 +729,32 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
private Map<Class<? extends IBaseResource>, IFhirResourceDao<?>> getDaos() { private Map<Class<? extends IBaseResource>, IFhirResourceDao<?>> getDaos() {
if (myResourceTypeToDao == null) { if (myResourceTypeToDao == null) {
Map<Class<? extends IBaseResource>, IFhirResourceDao<?>> theResourceTypeToDao = new HashMap<>(); Map<Class<? extends IBaseResource>, IFhirResourceDao<?>> resourceTypeToDao = new HashMap<>();
Map<String, IFhirResourceDao> daos = myApplicationContext.getBeansOfType(IFhirResourceDao.class, false, false); Map<String, IFhirResourceDao> daos = myApplicationContext.getBeansOfType(IFhirResourceDao.class, false, false);
String[] beanNames = myApplicationContext.getBeanNamesForType(IFhirResourceDao.class);
for (IFhirResourceDao<?> next : daos.values()) { for (IFhirResourceDao<?> next : daos.values()) {
theResourceTypeToDao.put(next.getResourceType(), next); resourceTypeToDao.put(next.getResourceType(), next);
} }
if (this instanceof IFhirResourceDao<?>) { if (this instanceof IFhirResourceDao<?>) {
IFhirResourceDao<?> thiz = (IFhirResourceDao<?>) this; IFhirResourceDao<?> thiz = (IFhirResourceDao<?>) this;
theResourceTypeToDao.put(thiz.getResourceType(), thiz); resourceTypeToDao.put(thiz.getResourceType(), thiz);
} }
myResourceTypeToDao = theResourceTypeToDao; myResourceTypeToDao = resourceTypeToDao;
} }
return Collections.unmodifiableMap(myResourceTypeToDao); return Collections.unmodifiableMap(myResourceTypeToDao);
} }
@PostConstruct
public void startClearCaches() {
myResourceTypeToDao = null;
}
protected Set<ResourceIndexedSearchParamCoords> extractSearchParamCoords(ResourceTable theEntity, IBaseResource theResource) { protected Set<ResourceIndexedSearchParamCoords> extractSearchParamCoords(ResourceTable theEntity, IBaseResource theResource) {
return mySearchParamExtractor.extractSearchParamCoords(theEntity, theResource); return mySearchParamExtractor.extractSearchParamCoords(theEntity, theResource);
@ -948,7 +959,14 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
@Override @Override
public void setApplicationContext(ApplicationContext theApplicationContext) throws BeansException { public void setApplicationContext(ApplicationContext theApplicationContext) throws BeansException {
myApplicationContext = theApplicationContext; /*
* We do a null check here because Smile's module system tries to
* initialize the application context twice if two modules depend on
* the persistence module. The second time sets the dependency's appctx.
*/
if (myApplicationContext == null) {
myApplicationContext = theApplicationContext;
}
} }
public void setConfig(DaoConfig theConfig) { public void setConfig(DaoConfig theConfig) {

View File

@ -1336,5 +1336,9 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
} }
} }
@PostConstruct
public void start() {
ourLog.info("Starting resource DAO for type: {}", getResourceName());
}
} }

View File

@ -305,7 +305,7 @@ public abstract class BaseHapiFhirSystemDao<T, MT> extends BaseHapiFhirDao<IBase
final IBaseResource resource = toResource(resourceTable, false); final IBaseResource resource = toResource(resourceTable, false);
@SuppressWarnings("rawtypes") final IFhirResourceDao dao = getDao(resource.getClass()); @SuppressWarnings("rawtypes") final IFhirResourceDao dao = getDaoOrThrowException(resource.getClass());
dao.reindex(resource, resourceTable); dao.reindex(resource, resourceTable);
return null; return null;

View File

@ -16,6 +16,7 @@ import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType; import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity; import org.apache.http.entity.StringEntity;
import org.hamcrest.Matchers;
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.r4.model.Bundle; import org.hl7.fhir.r4.model.Bundle;
@ -35,6 +36,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.stream.Collectors;
import static org.hamcrest.Matchers.startsWith; import static org.hamcrest.Matchers.startsWith;
import static org.junit.Assert.*; import static org.junit.Assert.*;
@ -174,12 +176,6 @@ public class ResourceProviderInterceptorR4Test extends BaseResourceProviderR4Tes
ResourceProviderInterceptorR4Test.verifyDaoInterceptor(myDaoInterceptor); ResourceProviderInterceptorR4Test.verifyDaoInterceptor(myDaoInterceptor);
} }
/*
* This is a weird way of verifying, but because this class
* is a child of a superclass that has other test children
* it's possible that other tests are hitting the server
* at the same time
*/
@Test @Test
public void testCreateResourceInTransaction() throws IOException { public void testCreateResourceInTransaction() throws IOException {
String methodName = "testCreateResourceInTransaction"; String methodName = "testCreateResourceInTransaction";
@ -220,15 +216,17 @@ public class ResourceProviderInterceptorR4Test extends BaseResourceProviderR4Tes
* DAO Interceptor * DAO Interceptor
*/ */
/*
* Sometimes we get more than 2 hits of the incomingRequestPreHandled
* method. My working theory is that it's a scheduled background job,
* such as the subscription interceptor or the search parameter cache
* updating.
*/
ardCaptor = ArgumentCaptor.forClass(ActionRequestDetails.class); ardCaptor = ArgumentCaptor.forClass(ActionRequestDetails.class);
opTypeCaptor = ArgumentCaptor.forClass(RestOperationTypeEnum.class); opTypeCaptor = ArgumentCaptor.forClass(RestOperationTypeEnum.class);
verify(myDaoInterceptor, times(2)).incomingRequestPreHandled(opTypeCaptor.capture(), ardCaptor.capture()); verify(myDaoInterceptor, atLeast(2)).incomingRequestPreHandled(opTypeCaptor.capture(), ardCaptor.capture());
assertEquals(RestOperationTypeEnum.TRANSACTION, opTypeCaptor.getAllValues().get(0)); assertThat(ardCaptor.getAllValues().stream().map(ActionRequestDetails::getResourceType).collect(Collectors.toList()), Matchers.contains("Bundle", "Patient"));
assertEquals("Bundle", ardCaptor.getAllValues().get(0).getResourceType()); assertThat(opTypeCaptor.getAllValues(), Matchers.contains(RestOperationTypeEnum.TRANSACTION, RestOperationTypeEnum.CREATE));
assertNotNull(ardCaptor.getAllValues().get(0).getResource());
assertEquals(RestOperationTypeEnum.CREATE, opTypeCaptor.getAllValues().get(1));
assertEquals("Patient", ardCaptor.getAllValues().get(1).getResourceType());
assertNotNull(ardCaptor.getAllValues().get(1).getResource());
rdCaptor = ArgumentCaptor.forClass(RequestDetails.class); rdCaptor = ArgumentCaptor.forClass(RequestDetails.class);
srCaptor = ArgumentCaptor.forClass(HttpServletRequest.class); srCaptor = ArgumentCaptor.forClass(HttpServletRequest.class);

View File

@ -31,7 +31,7 @@ public interface IServerConformanceProvider<T extends IBaseResource> {
* *
* See the class documentation for an important note if you are extending this class * See the class documentation for an important note if you are extending this class
*/ */
public abstract T getServerConformance(HttpServletRequest theRequest); T getServerConformance(HttpServletRequest theRequest);
/** /**
* This setter is needed in implementation classes (along with * This setter is needed in implementation classes (along with
@ -40,5 +40,5 @@ public interface IServerConformanceProvider<T extends IBaseResource> {
* *
* @param theRestfulServer * @param theRestfulServer
*/ */
public void setRestfulServer(RestfulServer theRestfulServer); void setRestfulServer(RestfulServer theRestfulServer);
} }

View File

@ -26,6 +26,7 @@ import ca.uhn.fhir.context.ProvidedResourceScanner;
import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.context.api.AddProfileTagEnum; import ca.uhn.fhir.context.api.AddProfileTagEnum;
import ca.uhn.fhir.context.api.BundleInclusionRule; import ca.uhn.fhir.context.api.BundleInclusionRule;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.parser.IParser; import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.annotation.Destroy; import ca.uhn.fhir.rest.annotation.Destroy;
import ca.uhn.fhir.rest.annotation.IdParam; import ca.uhn.fhir.rest.annotation.IdParam;
@ -125,6 +126,7 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
private boolean myUncompressIncomingContents = true; private boolean myUncompressIncomingContents = true;
private boolean myUseBrowserFriendlyContentTypes; private boolean myUseBrowserFriendlyContentTypes;
private ITenantIdentificationStrategy myTenantIdentificationStrategy; private ITenantIdentificationStrategy myTenantIdentificationStrategy;
private Date myConformanceDate;
/** /**
* Constructor. Note that if no {@link FhirContext} is passed in to the server (either through the constructor, or * Constructor. Note that if no {@link FhirContext} is passed in to the server (either through the constructor, or
@ -194,19 +196,14 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
result.setServerName(getServerName()); result.setServerName(getServerName());
result.setFhirContext(getFhirContext()); result.setFhirContext(getFhirContext());
result.setServerAddressStrategy(myServerAddressStrategy); result.setServerAddressStrategy(myServerAddressStrategy);
InputStream inputStream = null; try (InputStream inputStream = getClass().getResourceAsStream("/META-INF/MANIFEST.MF")) {
try {
inputStream = getClass().getResourceAsStream("/META-INF/MANIFEST.MF");
if (inputStream != null) { if (inputStream != null) {
Manifest manifest = new Manifest(inputStream); Manifest manifest = new Manifest(inputStream);
result.setConformanceDate(manifest.getMainAttributes().getValue("Build-Time")); String value = manifest.getMainAttributes().getValue("Build-Time");
result.setConformanceDate(new InstantDt(value));
} }
} catch (IOException e) { } catch (Exception e) {
// fall through // fall through
} finally {
if (inputStream != null) {
IOUtils.closeQuietly(inputStream);
}
} }
return result; return result;
} }
@ -573,10 +570,10 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
* *
* @param theList The list of interceptors (may be null) * @param theList The list of interceptors (may be null)
*/ */
public void setInterceptors(List<IServerInterceptor> theList) { public void setInterceptors(IServerInterceptor... theList) {
myInterceptors.clear(); myInterceptors.clear();
if (theList != null) { if (theList != null) {
myInterceptors.addAll(theList); myInterceptors.addAll(Arrays.asList(theList));
} }
} }
@ -606,8 +603,11 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
* *
* @see #setResourceProviders(Collection) * @see #setResourceProviders(Collection)
*/ */
public void setPlainProviders(Object... theProv) { public void setPlainProviders(Collection<Object> theProviders) {
setPlainProviders(Arrays.asList(theProv)); myPlainProviders.clear();
if (theProviders != null) {
myPlainProviders.addAll(theProviders);
}
} }
/** /**
@ -637,10 +637,10 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
/** /**
* Sets the resource providers for this server * Sets the resource providers for this server
*/ */
public void setResourceProviders(IResourceProvider... theResourceProviders) { public void setResourceProviders(Collection<IResourceProvider> theResourceProviders) {
myResourceProviders.clear(); myResourceProviders.clear();
if (theResourceProviders != null) { if (theResourceProviders != null) {
myResourceProviders.addAll(Arrays.asList(theResourceProviders)); myResourceProviders.addAll(theResourceProviders);
} }
} }
@ -1518,10 +1518,10 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
* *
* @param theList The list of interceptors (may be null) * @param theList The list of interceptors (may be null)
*/ */
public void setInterceptors(IServerInterceptor... theList) { public void setInterceptors(List<IServerInterceptor> theList) {
myInterceptors.clear(); myInterceptors.clear();
if (theList != null) { if (theList != null) {
myInterceptors.addAll(Arrays.asList(theList)); myInterceptors.addAll(theList);
} }
} }
@ -1530,11 +1530,8 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
* *
* @see #setResourceProviders(Collection) * @see #setResourceProviders(Collection)
*/ */
public void setPlainProviders(Collection<Object> theProviders) { public void setPlainProviders(Object... theProv) {
myPlainProviders.clear(); setPlainProviders(Arrays.asList(theProv));
if (theProviders != null) {
myPlainProviders.addAll(theProviders);
}
} }
/** /**
@ -1552,10 +1549,10 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
/** /**
* Sets the resource providers for this server * Sets the resource providers for this server
*/ */
public void setResourceProviders(Collection<IResourceProvider> theResourceProviders) { public void setResourceProviders(IResourceProvider... theResourceProviders) {
myResourceProviders.clear(); myResourceProviders.clear();
if (theResourceProviders != null) { if (theResourceProviders != null) {
myResourceProviders.addAll(theResourceProviders); myResourceProviders.addAll(Arrays.asList(theResourceProviders));
} }
} }

View File

@ -21,11 +21,13 @@ package ca.uhn.fhir.rest.server;
*/ */
import java.util.Collection; import java.util.Collection;
import java.util.Date;
import java.util.List; import java.util.List;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.rest.server.method.BaseMethodBinding; import ca.uhn.fhir.rest.server.method.BaseMethodBinding;
import ca.uhn.fhir.util.VersionUtil; import ca.uhn.fhir.util.VersionUtil;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import static org.apache.commons.lang3.StringUtils.isBlank; import static org.apache.commons.lang3.StringUtils.isBlank;
@ -38,7 +40,7 @@ public class RestulfulServerConfiguration {
private String serverName = "HAPI FHIR"; private String serverName = "HAPI FHIR";
private FhirContext fhirContext; private FhirContext fhirContext;
private IServerAddressStrategy serverAddressStrategy; private IServerAddressStrategy serverAddressStrategy;
private String conformanceDate; private IPrimitiveType<Date> myConformanceDate;
/** /**
* Constructor * Constructor
@ -73,11 +75,10 @@ public class RestulfulServerConfiguration {
} }
/** /**
* Set the serverBindings * Set the theServerBindings
* @param serverBindings the serverBindings to set
*/ */
public RestulfulServerConfiguration setServerBindings(List<BaseMethodBinding<?>> serverBindings) { public RestulfulServerConfiguration setServerBindings(List<BaseMethodBinding<?>> theServerBindings) {
this.serverBindings = serverBindings; this.serverBindings = theServerBindings;
return this; return this;
} }
@ -169,20 +170,22 @@ public class RestulfulServerConfiguration {
} }
/** /**
* Get the conformanceDate * Get the date that will be specified in the conformance profile
* @return the conformanceDate * exported by this server. Typically this would be populated with
*/ * an InstanceType.
public String getConformanceDate() { */
return conformanceDate; public IPrimitiveType<Date> getConformanceDate() {
return myConformanceDate;
} }
/** /**
* Set the conformanceDate * Set the date that will be specified in the conformance profile
* @param conformanceDate the conformanceDate to set * exported by this server. Typically this would be populated with
* an InstanceType.
*/ */
public void setConformanceDate(String conformanceDate) { public void setConformanceDate(IPrimitiveType<Date> theConformanceDate) {
this.conformanceDate = conformanceDate; myConformanceDate = theConformanceDate;
} }
} }

View File

@ -49,6 +49,7 @@ import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import ca.uhn.fhir.rest.server.method.*; import ca.uhn.fhir.rest.server.method.*;
import ca.uhn.fhir.rest.server.method.OperationMethodBinding.ReturnType; import ca.uhn.fhir.rest.server.method.OperationMethodBinding.ReturnType;
import ca.uhn.fhir.rest.server.method.SearchParameter; import ca.uhn.fhir.rest.server.method.SearchParameter;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
/** /**
* Server FHIR Provider which serves the conformance statement for a RESTful server implementation * Server FHIR Provider which serves the conformance statement for a RESTful server implementation
@ -132,10 +133,10 @@ public class ServerConformanceProvider implements IServerConformanceProvider<Con
} }
private DateTimeType conformanceDate() { private DateTimeType conformanceDate() {
String buildDate = getServerConfiguration().getConformanceDate(); IPrimitiveType<Date> buildDate = getServerConfiguration().getConformanceDate();
if (buildDate != null) { if (buildDate != null && buildDate.getValue() != null) {
try { try {
return new DateTimeType(buildDate); return new DateTimeType(buildDate.getValueAsString());
} catch (DataFormatException e) { } catch (DataFormatException e) {
// fall through // fall through
} }

View File

@ -30,6 +30,7 @@ import ca.uhn.fhir.rest.server.method.*;
import ca.uhn.fhir.rest.server.method.OperationMethodBinding.ReturnType; import ca.uhn.fhir.rest.server.method.OperationMethodBinding.ReturnType;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@ -136,10 +137,10 @@ public class ServerConformanceProvider implements IServerConformanceProvider<Con
} }
private DateTimeDt conformanceDate() { private DateTimeDt conformanceDate() {
String buildDate = getServerConfiguration().getConformanceDate(); IPrimitiveType<Date> buildDate = getServerConfiguration().getConformanceDate();
if (buildDate != null) { if (buildDate != null && buildDate.getValue() != null) {
try { try {
return new DateTimeDt(buildDate); return new DateTimeDt(buildDate.getValueAsString());
} catch (DataFormatException e) { } catch (DataFormatException e) {
// fall through // fall through
} }

View File

@ -27,6 +27,7 @@ import org.hl7.fhir.dstu3.model.OperationDefinition.OperationKind;
import org.hl7.fhir.dstu3.model.OperationDefinition.OperationParameterUse; import org.hl7.fhir.dstu3.model.OperationDefinition.OperationParameterUse;
import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@ -76,7 +77,7 @@ public class ServerCapabilityStatementProvider implements IServerConformanceProv
private Callable<RestulfulServerConfiguration> myServerConfiguration; private Callable<RestulfulServerConfiguration> myServerConfiguration;
/** /**
* No-arg constructor and seetter so that the ServerConfirmanceProvider can be Spring-wired with the RestfulService avoiding the potential reference cycle that would happen. * No-arg constructor and setter so that the ServerConformanceProvider can be Spring-wired with the RestfulService avoiding the potential reference cycle that would happen.
*/ */
public ServerCapabilityStatementProvider() { public ServerCapabilityStatementProvider() {
super(); super();
@ -139,10 +140,10 @@ public class ServerCapabilityStatementProvider implements IServerConformanceProv
} }
private DateTimeType conformanceDate() { private DateTimeType conformanceDate() {
String buildDate = getServerConfiguration().getConformanceDate(); IPrimitiveType<Date> buildDate = getServerConfiguration().getConformanceDate();
if (buildDate != null) { if (buildDate != null && buildDate.getValue() != null) {
try { try {
return new DateTimeType(buildDate); return new DateTimeType(buildDate.getValueAsString());
} catch (DataFormatException e) { } catch (DataFormatException e) {
// fall through // fall through
} }

View File

@ -15,6 +15,7 @@ import java.util.*;
import javax.servlet.ServletConfig; import javax.servlet.ServletConfig;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import ca.uhn.fhir.model.primitive.InstantDt;
import org.hl7.fhir.dstu3.model.*; import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.dstu3.model.CapabilityStatement.*; import org.hl7.fhir.dstu3.model.CapabilityStatement.*;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
@ -527,29 +528,42 @@ public class ServerCapabilityStatementProviderDstu3Test {
@Test @Test
public void testSearchReferenceParameterWithList() throws Exception { public void testSearchReferenceParameterWithList() throws Exception {
RestfulServer rsNoType = new RestfulServer(ourCtx); RestfulServer rsNoType = new RestfulServer(ourCtx){
@Override
public RestulfulServerConfiguration createConfiguration() {
RestulfulServerConfiguration retVal = super.createConfiguration();
retVal.setConformanceDate(new InstantDt("2011-02-22T11:22:33Z"));
return retVal;
}
};
rsNoType.registerProvider(new SearchProviderWithListNoType()); rsNoType.registerProvider(new SearchProviderWithListNoType());
ServerCapabilityStatementProvider scNoType = new ServerCapabilityStatementProvider(rsNoType); ServerCapabilityStatementProvider scNoType = new ServerCapabilityStatementProvider(rsNoType);
rsNoType.setServerConformanceProvider(scNoType); rsNoType.setServerConformanceProvider(scNoType);
rsNoType.init(createServletConfig()); rsNoType.init(createServletConfig());
scNoType.getServerConfiguration().setConformanceDate("2011-02-22T11:22:33Z");
CapabilityStatement conformance = scNoType.getServerConformance(createHttpServletRequest()); CapabilityStatement conformance = scNoType.getServerConformance(createHttpServletRequest());
String confNoType = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(conformance); String confNoType = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(conformance);
ourLog.info(confNoType); ourLog.info(confNoType);
RestfulServer rsWithType = new RestfulServer(ourCtx); RestfulServer rsWithType = new RestfulServer(ourCtx){
@Override
public RestulfulServerConfiguration createConfiguration() {
RestulfulServerConfiguration retVal = super.createConfiguration();
retVal.setConformanceDate(new InstantDt("2011-02-22T11:22:33Z"));
return retVal;
}
};
rsWithType.registerProvider(new SearchProviderWithListWithType()); rsWithType.registerProvider(new SearchProviderWithListWithType());
ServerCapabilityStatementProvider scWithType = new ServerCapabilityStatementProvider(rsWithType); ServerCapabilityStatementProvider scWithType = new ServerCapabilityStatementProvider(rsWithType);
rsWithType.setServerConformanceProvider(scWithType); rsWithType.setServerConformanceProvider(scWithType);
rsWithType.init(createServletConfig()); rsWithType.init(createServletConfig());
scWithType.getServerConfiguration().setConformanceDate("2011-02-22T11:22:33Z");
CapabilityStatement conformanceWithType = scWithType.getServerConformance(createHttpServletRequest()); CapabilityStatement conformanceWithType = scWithType.getServerConformance(createHttpServletRequest());
String confWithType = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(conformanceWithType); String confWithType = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(conformanceWithType);
ourLog.info(confWithType); ourLog.info(confWithType);
assertEquals(confNoType, confWithType); assertEquals(confNoType, confWithType);
assertThat(confNoType, containsString("<date value=\"2011-02-22T11:22:33Z\"/>"));
} }
@Test @Test

View File

@ -50,6 +50,7 @@ import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import ca.uhn.fhir.rest.server.method.*; import ca.uhn.fhir.rest.server.method.*;
import ca.uhn.fhir.rest.server.method.OperationMethodBinding.ReturnType; import ca.uhn.fhir.rest.server.method.OperationMethodBinding.ReturnType;
import ca.uhn.fhir.rest.server.method.SearchParameter; import ca.uhn.fhir.rest.server.method.SearchParameter;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
/** /**
* Server FHIR Provider which serves the conformance statement for a RESTful * Server FHIR Provider which serves the conformance statement for a RESTful
@ -314,10 +315,10 @@ public class ServerConformanceProvider implements IServerConformanceProvider<Con
} }
private DateTimeType conformanceDate() { private DateTimeType conformanceDate() {
String buildDate = getServerConfiguration().getConformanceDate(); IPrimitiveType<Date> buildDate = getServerConfiguration().getConformanceDate();
if (buildDate != null) { if (buildDate != null && buildDate.getValue() != null) {
try { try {
return new DateTimeType(buildDate); return new DateTimeType(buildDate.getValueAsString());
} catch (DataFormatException e) { } catch (DataFormatException e) {
// fall through // fall through
} }

View File

@ -21,6 +21,7 @@ import ca.uhn.fhir.rest.server.method.SearchParameter;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.hl7.fhir.r4.model.*; import org.hl7.fhir.r4.model.*;
import org.hl7.fhir.r4.model.CapabilityStatement.*; import org.hl7.fhir.r4.model.CapabilityStatement.*;
import org.hl7.fhir.r4.model.Enumerations.PublicationStatus; import org.hl7.fhir.r4.model.Enumerations.PublicationStatus;
@ -139,10 +140,10 @@ public class ServerCapabilityStatementProvider implements IServerConformanceProv
} }
private DateTimeType conformanceDate() { private DateTimeType conformanceDate() {
String buildDate = getServerConfiguration().getConformanceDate(); IPrimitiveType<Date> buildDate = getServerConfiguration().getConformanceDate();
if (buildDate != null) { if (buildDate != null && buildDate.getValue() != null) {
try { try {
return new DateTimeType(buildDate); return new DateTimeType(buildDate.getValueAsString());
} catch (DataFormatException e) { } catch (DataFormatException e) {
// fall through // fall through
} }