Add ability for resource source to be specified by header
This commit is contained in:
parent
0d3f7d4a03
commit
385a885abf
|
@ -28,6 +28,7 @@ public class Constants {
|
||||||
|
|
||||||
public static final String CT_TEXT_CSV = "text/csv";
|
public static final String CT_TEXT_CSV = "text/csv";
|
||||||
public static final String HEADER_REQUEST_ID = "X-Request-ID";
|
public static final String HEADER_REQUEST_ID = "X-Request-ID";
|
||||||
|
public static final String HEADER_REQUEST_SOURCE = "X-Request-Source";
|
||||||
public static final String CACHE_CONTROL_MAX_RESULTS = "max-results";
|
public static final String CACHE_CONTROL_MAX_RESULTS = "max-results";
|
||||||
public static final String CACHE_CONTROL_NO_CACHE = "no-cache";
|
public static final String CACHE_CONTROL_NO_CACHE = "no-cache";
|
||||||
public static final String CACHE_CONTROL_NO_STORE = "no-store";
|
public static final String CACHE_CONTROL_NO_STORE = "no-store";
|
||||||
|
@ -242,6 +243,15 @@ public class Constants {
|
||||||
* Operation name for the $lastn operation
|
* Operation name for the $lastn operation
|
||||||
*/
|
*/
|
||||||
public static final String OPERATION_LASTN = "$lastn";
|
public static final String OPERATION_LASTN = "$lastn";
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* This extension represents the equivalent of the
|
||||||
|
* <code>Resource.meta.source</code> field within R4+ resources, and is for
|
||||||
|
* use in DSTU3 resources. It should contain a value of type <code>uri</code>
|
||||||
|
* and will be located on the Resource.meta
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public static final String EXT_META_SOURCE = "http://hapifhir.io/fhir/StructureDefinition/resource-meta-source";
|
||||||
|
|
||||||
static {
|
static {
|
||||||
CHARSET_UTF8 = StandardCharsets.UTF_8;
|
CHARSET_UTF8 = StandardCharsets.UTF_8;
|
||||||
|
|
|
@ -23,9 +23,9 @@ package ca.uhn.fhir.util;
|
||||||
import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
|
import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
|
||||||
import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
|
import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import org.hl7.fhir.instance.model.api.IBase;
|
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseMetaType;
|
import ca.uhn.fhir.rest.api.Constants;
|
||||||
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
import org.hl7.fhir.instance.model.api.*;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -46,6 +46,30 @@ public class MetaUtil {
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the value for <code>Resource.meta.source</code> for R4+ resources, and places the value in
|
||||||
|
* an extension on <code>Resource.meta</code>
|
||||||
|
* with the URL <code>http://hapifhir.io/fhir/StructureDefinition/resource-meta-source</code> for DSTU3
|
||||||
|
* and below.
|
||||||
|
*
|
||||||
|
* @param theContext The FhirContext object
|
||||||
|
* @param theResource The resource to modify
|
||||||
|
* @param theValue The source URI
|
||||||
|
* @see <a href="http://hl7.org/fhir/resource-definitions.html#Resource.meta">Meta.source</a>
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static void setSource(FhirContext theContext, IBaseResource theResource, String theValue) {
|
||||||
|
if (theContext.getVersion().getVersion().isEqualOrNewerThan(FhirVersionEnum.R4)) {
|
||||||
|
MetaUtil.setSource(theContext, theResource.getMeta(), theValue);
|
||||||
|
} else {
|
||||||
|
IBaseExtension<?, ?> sourceExtension = ((IBaseHasExtensions) theResource.getMeta()).addExtension();
|
||||||
|
sourceExtension.setUrl(Constants.EXT_META_SOURCE);
|
||||||
|
IPrimitiveType<String> value = (IPrimitiveType<String>) theContext.getElementDefinition("uri").newInstance();
|
||||||
|
value.setValue(theValue);
|
||||||
|
sourceExtension.setValue(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void setSource(FhirContext theContext, IBaseMetaType theMeta, String theValue) {
|
public static void setSource(FhirContext theContext, IBaseMetaType theMeta, String theValue) {
|
||||||
BaseRuntimeElementCompositeDefinition<?> elementDef = (BaseRuntimeElementCompositeDefinition<?>) theContext.getElementDefinition(theMeta.getClass());
|
BaseRuntimeElementCompositeDefinition<?> elementDef = (BaseRuntimeElementCompositeDefinition<?>) theContext.getElementDefinition(theMeta.getClass());
|
||||||
BaseRuntimeChildDefinition sourceChild = elementDef.getChildByName("source");
|
BaseRuntimeChildDefinition sourceChild = elementDef.getChildByName("source");
|
||||||
|
|
|
@ -25,7 +25,6 @@ import ca.uhn.fhir.jpa.searchparam.extractor.LogicalReferenceHelper;
|
||||||
import ca.uhn.fhir.jpa.searchparam.extractor.ResourceIndexedSearchParams;
|
import ca.uhn.fhir.jpa.searchparam.extractor.ResourceIndexedSearchParams;
|
||||||
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
|
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
|
||||||
import ca.uhn.fhir.jpa.sp.ISearchParamPresenceSvc;
|
import ca.uhn.fhir.jpa.sp.ISearchParamPresenceSvc;
|
||||||
import ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc;
|
|
||||||
import ca.uhn.fhir.jpa.term.api.ITermReadSvc;
|
import ca.uhn.fhir.jpa.term.api.ITermReadSvc;
|
||||||
import ca.uhn.fhir.jpa.util.AddRemoveCount;
|
import ca.uhn.fhir.jpa.util.AddRemoveCount;
|
||||||
import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster;
|
import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster;
|
||||||
|
@ -900,15 +899,8 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
|
||||||
+ (isNotBlank(provenanceRequestId) ? "#" : "")
|
+ (isNotBlank(provenanceRequestId) ? "#" : "")
|
||||||
+ defaultString(provenanceRequestId);
|
+ defaultString(provenanceRequestId);
|
||||||
|
|
||||||
if (myContext.getVersion().getVersion().equals(FhirVersionEnum.DSTU3)) {
|
MetaUtil.setSource(myContext, retVal, sourceString);
|
||||||
IBaseExtension<?, ?> sourceExtension = ((IBaseHasExtensions) retVal.getMeta()).addExtension();
|
|
||||||
sourceExtension.setUrl(JpaConstants.EXT_META_SOURCE);
|
|
||||||
IPrimitiveType<String> value = (IPrimitiveType<String>) myContext.getElementDefinition("uri").newInstance();
|
|
||||||
value.setValue(sourceString);
|
|
||||||
sourceExtension.setValue(value);
|
|
||||||
} else if (myContext.getVersion().getVersion().isEqualOrNewerThan(FhirVersionEnum.R4)) {
|
|
||||||
MetaUtil.setSource(myContext, retVal.getMeta(), sourceString);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return retVal;
|
return retVal;
|
||||||
|
@ -1078,7 +1070,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
|
||||||
source = ((IBaseHasExtensions) theResource.getMeta())
|
source = ((IBaseHasExtensions) theResource.getMeta())
|
||||||
.getExtension()
|
.getExtension()
|
||||||
.stream()
|
.stream()
|
||||||
.filter(t -> JpaConstants.EXT_META_SOURCE.equals(t.getUrl()))
|
.filter(t -> Constants.EXT_META_SOURCE.equals(t.getUrl()))
|
||||||
.filter(t -> t.getValue() instanceof IPrimitiveType)
|
.filter(t -> t.getValue() instanceof IPrimitiveType)
|
||||||
.map(t -> ((IPrimitiveType) t.getValue()).getValueAsString())
|
.map(t -> ((IPrimitiveType) t.getValue()).getValueAsString())
|
||||||
.findFirst()
|
.findFirst()
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package ca.uhn.fhir.jpa.dao.dstu3;
|
package ca.uhn.fhir.jpa.dao.dstu3;
|
||||||
|
|
||||||
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
||||||
import ca.uhn.fhir.jpa.model.util.JpaConstants;
|
|
||||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||||
import ca.uhn.fhir.jpa.util.TestUtil;
|
import ca.uhn.fhir.jpa.util.TestUtil;
|
||||||
import ca.uhn.fhir.rest.api.Constants;
|
import ca.uhn.fhir.rest.api.Constants;
|
||||||
|
@ -46,12 +45,12 @@ public class FhirResourceDaoDstu3SourceTest extends BaseJpaDstu3Test {
|
||||||
|
|
||||||
when(mySrd.getRequestId()).thenReturn(requestId);
|
when(mySrd.getRequestId()).thenReturn(requestId);
|
||||||
Patient pt0 = new Patient();
|
Patient pt0 = new Patient();
|
||||||
pt0.getMeta().addExtension(JpaConstants.EXT_META_SOURCE, new StringType("urn:source:0"));
|
pt0.getMeta().addExtension(Constants.EXT_META_SOURCE, new StringType("urn:source:0"));
|
||||||
pt0.setActive(true);
|
pt0.setActive(true);
|
||||||
IIdType pt0id = myPatientDao.create(pt0, mySrd).getId().toUnqualifiedVersionless();
|
IIdType pt0id = myPatientDao.create(pt0, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
Patient pt1 = new Patient();
|
Patient pt1 = new Patient();
|
||||||
pt1.getMeta().addExtension(JpaConstants.EXT_META_SOURCE, new StringType("urn:source:1"));
|
pt1.getMeta().addExtension(Constants.EXT_META_SOURCE, new StringType("urn:source:1"));
|
||||||
pt1.setActive(true);
|
pt1.setActive(true);
|
||||||
IIdType pt1id = myPatientDao.create(pt1, mySrd).getId().toUnqualifiedVersionless();
|
IIdType pt1id = myPatientDao.create(pt1, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
|
@ -62,7 +61,7 @@ public class FhirResourceDaoDstu3SourceTest extends BaseJpaDstu3Test {
|
||||||
IBundleProvider result = myPatientDao.search(params);
|
IBundleProvider result = myPatientDao.search(params);
|
||||||
assertThat(toUnqualifiedVersionlessIdValues(result), containsInAnyOrder(pt0id.getValue()));
|
assertThat(toUnqualifiedVersionlessIdValues(result), containsInAnyOrder(pt0id.getValue()));
|
||||||
pt0 = (Patient) result.getResources(0, 1).get(0);
|
pt0 = (Patient) result.getResources(0, 1).get(0);
|
||||||
assertEquals("urn:source:0#a_request_id", pt0.getMeta().getExtensionString(JpaConstants.EXT_META_SOURCE));
|
assertEquals("urn:source:0#a_request_id", pt0.getMeta().getExtensionString(Constants.EXT_META_SOURCE));
|
||||||
|
|
||||||
// Search by request ID
|
// Search by request ID
|
||||||
params = new SearchParameterMap();
|
params = new SearchParameterMap();
|
||||||
|
@ -87,17 +86,17 @@ public class FhirResourceDaoDstu3SourceTest extends BaseJpaDstu3Test {
|
||||||
|
|
||||||
when(mySrd.getRequestId()).thenReturn(requestId);
|
when(mySrd.getRequestId()).thenReturn(requestId);
|
||||||
Patient pt0 = new Patient();
|
Patient pt0 = new Patient();
|
||||||
pt0.getMeta().addExtension(JpaConstants.EXT_META_SOURCE, new StringType("urn:source:0"));
|
pt0.getMeta().addExtension(Constants.EXT_META_SOURCE, new StringType("urn:source:0"));
|
||||||
pt0.setActive(true);
|
pt0.setActive(true);
|
||||||
IIdType pt0id = myPatientDao.create(pt0, mySrd).getId().toUnqualifiedVersionless();
|
IIdType pt0id = myPatientDao.create(pt0, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
Patient pt1 = new Patient();
|
Patient pt1 = new Patient();
|
||||||
pt1.getMeta().addExtension(JpaConstants.EXT_META_SOURCE, new StringType("urn:source:1"));
|
pt1.getMeta().addExtension(Constants.EXT_META_SOURCE, new StringType("urn:source:1"));
|
||||||
pt1.setActive(true);
|
pt1.setActive(true);
|
||||||
IIdType pt1id = myPatientDao.create(pt1, mySrd).getId().toUnqualifiedVersionless();
|
IIdType pt1id = myPatientDao.create(pt1, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
Patient pt2 = new Patient();
|
Patient pt2 = new Patient();
|
||||||
pt2.getMeta().addExtension(JpaConstants.EXT_META_SOURCE, new StringType("urn:source:2"));
|
pt2.getMeta().addExtension(Constants.EXT_META_SOURCE, new StringType("urn:source:2"));
|
||||||
pt2.setActive(true);
|
pt2.setActive(true);
|
||||||
myPatientDao.create(pt2, mySrd).getId().toUnqualifiedVersionless();
|
myPatientDao.create(pt2, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
|
@ -118,17 +117,17 @@ public class FhirResourceDaoDstu3SourceTest extends BaseJpaDstu3Test {
|
||||||
|
|
||||||
when(mySrd.getRequestId()).thenReturn(requestId);
|
when(mySrd.getRequestId()).thenReturn(requestId);
|
||||||
Patient pt0 = new Patient();
|
Patient pt0 = new Patient();
|
||||||
pt0.getMeta().addExtension(JpaConstants.EXT_META_SOURCE, new StringType("urn:source:0"));
|
pt0.getMeta().addExtension(Constants.EXT_META_SOURCE, new StringType("urn:source:0"));
|
||||||
pt0.setActive(true);
|
pt0.setActive(true);
|
||||||
IIdType pt0id = myPatientDao.create(pt0, mySrd).getId().toUnqualifiedVersionless();
|
IIdType pt0id = myPatientDao.create(pt0, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
Patient pt1 = new Patient();
|
Patient pt1 = new Patient();
|
||||||
pt1.getMeta().addExtension(JpaConstants.EXT_META_SOURCE, new StringType("urn:source:1"));
|
pt1.getMeta().addExtension(Constants.EXT_META_SOURCE, new StringType("urn:source:1"));
|
||||||
pt1.setActive(true);
|
pt1.setActive(true);
|
||||||
IIdType pt1id = myPatientDao.create(pt1, mySrd).getId().toUnqualifiedVersionless();
|
IIdType pt1id = myPatientDao.create(pt1, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
Patient pt2 = new Patient();
|
Patient pt2 = new Patient();
|
||||||
pt2.getMeta().addExtension(JpaConstants.EXT_META_SOURCE, new StringType("urn:source:2"));
|
pt2.getMeta().addExtension(Constants.EXT_META_SOURCE, new StringType("urn:source:2"));
|
||||||
pt2.setActive(true);
|
pt2.setActive(true);
|
||||||
myPatientDao.create(pt2, mySrd).getId().toUnqualifiedVersionless();
|
myPatientDao.create(pt2, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
|
@ -148,7 +147,7 @@ public class FhirResourceDaoDstu3SourceTest extends BaseJpaDstu3Test {
|
||||||
when(mySrd.getRequestId()).thenReturn(requestId);
|
when(mySrd.getRequestId()).thenReturn(requestId);
|
||||||
|
|
||||||
Patient pt0 = new Patient();
|
Patient pt0 = new Patient();
|
||||||
pt0.getMeta().addExtension(JpaConstants.EXT_META_SOURCE, new StringType("urn:source:0"));
|
pt0.getMeta().addExtension(Constants.EXT_META_SOURCE, new StringType("urn:source:0"));
|
||||||
pt0.setActive(true);
|
pt0.setActive(true);
|
||||||
IIdType pt0id = myPatientDao.create(pt0, mySrd).getId().toUnqualifiedVersionless();
|
IIdType pt0id = myPatientDao.create(pt0, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
|
@ -166,19 +165,19 @@ public class FhirResourceDaoDstu3SourceTest extends BaseJpaDstu3Test {
|
||||||
public void testSourceNotPreservedAcrossUpdate() {
|
public void testSourceNotPreservedAcrossUpdate() {
|
||||||
|
|
||||||
Patient pt0 = new Patient();
|
Patient pt0 = new Patient();
|
||||||
pt0.getMeta().addExtension(JpaConstants.EXT_META_SOURCE, new StringType("urn:source:0"));
|
pt0.getMeta().addExtension(Constants.EXT_META_SOURCE, new StringType("urn:source:0"));
|
||||||
pt0.setActive(true);
|
pt0.setActive(true);
|
||||||
IIdType pt0id = myPatientDao.create(pt0, mySrd).getId().toUnqualifiedVersionless();
|
IIdType pt0id = myPatientDao.create(pt0, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
pt0 = myPatientDao.read(pt0id);
|
pt0 = myPatientDao.read(pt0id);
|
||||||
assertEquals("urn:source:0", pt0.getMeta().getExtensionString(JpaConstants.EXT_META_SOURCE));
|
assertEquals("urn:source:0", pt0.getMeta().getExtensionString(Constants.EXT_META_SOURCE));
|
||||||
|
|
||||||
pt0.getMeta().getExtension().clear();
|
pt0.getMeta().getExtension().clear();
|
||||||
pt0.setActive(false);
|
pt0.setActive(false);
|
||||||
myPatientDao.update(pt0);
|
myPatientDao.update(pt0);
|
||||||
|
|
||||||
pt0 = myPatientDao.read(pt0id.withVersion("2"));
|
pt0 = myPatientDao.read(pt0id.withVersion("2"));
|
||||||
assertEquals(null, pt0.getMeta().getExtensionString(JpaConstants.EXT_META_SOURCE));
|
assertEquals(null, pt0.getMeta().getExtensionString(Constants.EXT_META_SOURCE));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,19 +187,19 @@ public class FhirResourceDaoDstu3SourceTest extends BaseJpaDstu3Test {
|
||||||
when(mySrd.getRequestId()).thenReturn("0000000000000000");
|
when(mySrd.getRequestId()).thenReturn("0000000000000000");
|
||||||
|
|
||||||
Patient pt0 = new Patient();
|
Patient pt0 = new Patient();
|
||||||
pt0.getMeta().addExtension(JpaConstants.EXT_META_SOURCE, new StringType("urn:source:0"));
|
pt0.getMeta().addExtension(Constants.EXT_META_SOURCE, new StringType("urn:source:0"));
|
||||||
pt0.setActive(true);
|
pt0.setActive(true);
|
||||||
IIdType pt0id = myPatientDao.create(pt0, mySrd).getId().toUnqualifiedVersionless();
|
IIdType pt0id = myPatientDao.create(pt0, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
pt0 = myPatientDao.read(pt0id);
|
pt0 = myPatientDao.read(pt0id);
|
||||||
assertEquals(null, pt0.getMeta().getExtensionString(JpaConstants.EXT_META_SOURCE));
|
assertEquals(null, pt0.getMeta().getExtensionString(Constants.EXT_META_SOURCE));
|
||||||
|
|
||||||
pt0.getMeta().addExtension(JpaConstants.EXT_META_SOURCE, new StringType("urn:source:1"));
|
pt0.getMeta().addExtension(Constants.EXT_META_SOURCE, new StringType("urn:source:1"));
|
||||||
pt0.setActive(false);
|
pt0.setActive(false);
|
||||||
myPatientDao.update(pt0);
|
myPatientDao.update(pt0);
|
||||||
|
|
||||||
pt0 = myPatientDao.read(pt0id.withVersion("2"));
|
pt0 = myPatientDao.read(pt0id.withVersion("2"));
|
||||||
assertEquals(null, pt0.getMeta().getExtensionString(JpaConstants.EXT_META_SOURCE));
|
assertEquals(null, pt0.getMeta().getExtensionString(Constants.EXT_META_SOURCE));
|
||||||
|
|
||||||
// Search without source param
|
// Search without source param
|
||||||
SearchParameterMap params = new SearchParameterMap();
|
SearchParameterMap params = new SearchParameterMap();
|
||||||
|
|
|
@ -3,7 +3,6 @@ package ca.uhn.fhir.jpa.provider.dstu3;
|
||||||
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
||||||
import ca.uhn.fhir.jpa.dao.data.ISearchDao;
|
import ca.uhn.fhir.jpa.dao.data.ISearchDao;
|
||||||
import ca.uhn.fhir.jpa.entity.Search;
|
import ca.uhn.fhir.jpa.entity.Search;
|
||||||
import ca.uhn.fhir.jpa.model.util.JpaConstants;
|
|
||||||
import ca.uhn.fhir.jpa.provider.r4.ResourceProviderR4Test;
|
import ca.uhn.fhir.jpa.provider.r4.ResourceProviderR4Test;
|
||||||
import ca.uhn.fhir.jpa.search.SearchCoordinatorSvcImpl;
|
import ca.uhn.fhir.jpa.search.SearchCoordinatorSvcImpl;
|
||||||
import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
|
import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
|
||||||
|
@ -3952,7 +3951,7 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
|
||||||
|
|
||||||
{
|
{
|
||||||
Patient readPatient = (Patient) ourClient.read().resource("Patient").withId(patientid).execute();
|
Patient readPatient = (Patient) ourClient.read().resource("Patient").withId(patientid).execute();
|
||||||
assertThat(readPatient.getMeta().getExtensionString(JpaConstants.EXT_META_SOURCE), matchesPattern("#[a-zA-Z0-9]+"));
|
assertThat(readPatient.getMeta().getExtensionString(Constants.EXT_META_SOURCE), matchesPattern("#[a-zA-Z0-9]+"));
|
||||||
}
|
}
|
||||||
|
|
||||||
patient.setId(patientid);
|
patient.setId(patientid);
|
||||||
|
@ -3960,12 +3959,12 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
|
||||||
ourClient.update().resource(patient).execute();
|
ourClient.update().resource(patient).execute();
|
||||||
{
|
{
|
||||||
Patient readPatient = (Patient) ourClient.read().resource("Patient").withId(patientid).execute();
|
Patient readPatient = (Patient) ourClient.read().resource("Patient").withId(patientid).execute();
|
||||||
assertThat(readPatient.getMeta().getExtensionString(JpaConstants.EXT_META_SOURCE), matchesPattern("#[a-zA-Z0-9]+"));
|
assertThat(readPatient.getMeta().getExtensionString(Constants.EXT_META_SOURCE), matchesPattern("#[a-zA-Z0-9]+"));
|
||||||
|
|
||||||
readPatient.addName().setFamily("testUpdateWithSource");
|
readPatient.addName().setFamily("testUpdateWithSource");
|
||||||
ourClient.update().resource(readPatient).execute();
|
ourClient.update().resource(readPatient).execute();
|
||||||
readPatient = (Patient) ourClient.read().resource("Patient").withId(patientid).execute();
|
readPatient = (Patient) ourClient.read().resource("Patient").withId(patientid).execute();
|
||||||
assertThat(readPatient.getMeta().getExtensionString(JpaConstants.EXT_META_SOURCE), matchesPattern("#[a-zA-Z0-9]+"));
|
assertThat(readPatient.getMeta().getExtensionString(Constants.EXT_META_SOURCE), matchesPattern("#[a-zA-Z0-9]+"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -243,16 +243,6 @@ public class JpaConstants {
|
||||||
*/
|
*/
|
||||||
public static final String EXTENSION_EXT_SYSTEMDEFINED = JpaConstants.class.getName() + "_EXTENSION_EXT_SYSTEMDEFINED";
|
public static final String EXTENSION_EXT_SYSTEMDEFINED = JpaConstants.class.getName() + "_EXTENSION_EXT_SYSTEMDEFINED";
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* This extension represents the equivalent of the
|
|
||||||
* <code>Resource.meta.source</code> field within R4+ resources, and is for
|
|
||||||
* use in DSTU3 resources. It should contain a value of type <code>uri</code>
|
|
||||||
* and will be located on the Resource.meta
|
|
||||||
* </p>
|
|
||||||
*/
|
|
||||||
public static final String EXT_META_SOURCE = "http://hapifhir.io/fhir/StructureDefinition/resource-meta-source";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parameter for the $export operation
|
* Parameter for the $export operation
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -370,7 +370,7 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
||||||
throw new ConfigurationException("Failure scanning class " + clazz.getSimpleName() + ": " + e.getMessage(), e);
|
throw new ConfigurationException("Failure scanning class " + clazz.getSimpleName() + ": " + e.getMessage(), e);
|
||||||
}
|
}
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
throw new ConfigurationException("Did not find any annotated RESTful methods on provider class " + theProvider.getClass().getCanonicalName());
|
throw new ConfigurationException("Did not find any annotated RESTful methods on provider class " + theProvider.getClass().getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
package ca.uhn.fhir.rest.server.interceptor;
|
||||||
|
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.interceptor.api.Hook;
|
||||||
|
import ca.uhn.fhir.interceptor.api.Interceptor;
|
||||||
|
import ca.uhn.fhir.interceptor.api.Pointcut;
|
||||||
|
import ca.uhn.fhir.rest.api.Constants;
|
||||||
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
|
import ca.uhn.fhir.util.MetaUtil;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This interceptor examines a header on the incoming request and places it in
|
||||||
|
* <code>Resource.meta.source</code> (R4 and above) or in an extension on <code>Resource.meta</code>
|
||||||
|
* with the URL <code>http://hapifhir.io/fhir/StructureDefinition/resource-meta-source</code> (DSTU3 and below).
|
||||||
|
* <p>
|
||||||
|
* This interceptor does not support versions of FHIR below DSTU3.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @see <a href="http://hl7.org/fhir/resource-definitions.html#Resource.meta">Meta.source</a>
|
||||||
|
*/
|
||||||
|
@Interceptor
|
||||||
|
public class CaptureResourceSourceFromHeaderInterceptor {
|
||||||
|
|
||||||
|
private static final Logger ourLog = LoggerFactory.getLogger(CaptureResourceSourceFromHeaderInterceptor.class);
|
||||||
|
private final FhirContext myFhirContext;
|
||||||
|
private String myHeaderName;
|
||||||
|
|
||||||
|
public CaptureResourceSourceFromHeaderInterceptor(FhirContext theFhirContext) {
|
||||||
|
myFhirContext = theFhirContext;
|
||||||
|
setHeaderName(Constants.HEADER_REQUEST_SOURCE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the header name to examine in incoming requests. Default is {@link ca.uhn.fhir.rest.api.Constants#HEADER_REQUEST_SOURCE "X-Request-Source"}.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("WeakerAccess")
|
||||||
|
public String getHeaderName() {
|
||||||
|
return myHeaderName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the header name to examine in incoming requests. Default is {@link ca.uhn.fhir.rest.api.Constants#HEADER_REQUEST_SOURCE "X-Request-Source"}.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("WeakerAccess")
|
||||||
|
public void setHeaderName(String theHeaderName) {
|
||||||
|
myHeaderName = theHeaderName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Hook(Pointcut.SERVER_INCOMING_REQUEST_PRE_HANDLED)
|
||||||
|
public void extractSource(RequestDetails theRequestDetails) {
|
||||||
|
IBaseResource resource = theRequestDetails.getResource();
|
||||||
|
if (resource != null) {
|
||||||
|
String requestSource = theRequestDetails.getHeader(getHeaderName());
|
||||||
|
if (isNotBlank(requestSource)) {
|
||||||
|
ourLog.trace("Setting Meta.source to \"{}\" because of header \"{}\"", requestSource, getHeaderName());
|
||||||
|
MetaUtil.setSource(myFhirContext, resource, requestSource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -126,6 +126,7 @@ public class HashMapResourceProvider<T extends IBaseResource> implements IResour
|
||||||
|
|
||||||
return new MethodOutcome()
|
return new MethodOutcome()
|
||||||
.setCreated(true)
|
.setCreated(true)
|
||||||
|
.setResource(theResource)
|
||||||
.setId(theResource.getIdElement());
|
.setId(theResource.getIdElement());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -373,6 +374,7 @@ public class HashMapResourceProvider<T extends IBaseResource> implements IResour
|
||||||
|
|
||||||
return new MethodOutcome()
|
return new MethodOutcome()
|
||||||
.setCreated(created)
|
.setCreated(created)
|
||||||
|
.setResource(theResource)
|
||||||
.setId(theResource.getIdElement());
|
.setId(theResource.getIdElement());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -416,6 +418,19 @@ public class HashMapResourceProvider<T extends IBaseResource> implements IResour
|
||||||
return theResource.getIdElement();
|
return theResource.getIdElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an unmodifiable list containing the current version of all resources stored in this provider
|
||||||
|
*
|
||||||
|
* @since 4.1.0
|
||||||
|
*/
|
||||||
|
public List<T> getStoredResources() {
|
||||||
|
List<T> retVal = new ArrayList<>();
|
||||||
|
for (TreeMap<Long, T> next : myIdToVersionToResourceMap.values()) {
|
||||||
|
retVal.add(next.lastEntry().getValue());
|
||||||
|
}
|
||||||
|
return Collections.unmodifiableList(retVal);
|
||||||
|
}
|
||||||
|
|
||||||
private static <T extends IBaseResource> T fireInterceptorsAndFilterAsNeeded(T theResource, RequestDetails theRequestDetails) {
|
private static <T extends IBaseResource> T fireInterceptorsAndFilterAsNeeded(T theResource, RequestDetails theRequestDetails) {
|
||||||
List<T> output = fireInterceptorsAndFilterAsNeeded(Lists.newArrayList(theResource), theRequestDetails);
|
List<T> output = fireInterceptorsAndFilterAsNeeded(Lists.newArrayList(theResource), theRequestDetails);
|
||||||
if (output.size() == 1) {
|
if (output.size() == 1) {
|
||||||
|
|
|
@ -87,9 +87,8 @@ public class SearchR4Test {
|
||||||
* A paging request that incorrectly executes at the type level shouldn't be grabbed by the search method binding
|
* A paging request that incorrectly executes at the type level shouldn't be grabbed by the search method binding
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void tesPageRequestCantTriggerSearchAccidentally() throws Exception {
|
public void testPageRequestCantTriggerSearchAccidentally() throws Exception {
|
||||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?" + Constants.PARAM_PAGINGACTION + "=12345");
|
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?" + Constants.PARAM_PAGINGACTION + "=12345");
|
||||||
Bundle bundle;
|
|
||||||
try (CloseableHttpResponse status = ourClient.execute(httpGet)) {
|
try (CloseableHttpResponse status = ourClient.execute(httpGet)) {
|
||||||
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
|
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||||
ourLog.info(responseContent);
|
ourLog.info(responseContent);
|
||||||
|
|
|
@ -0,0 +1,102 @@
|
||||||
|
package ca.uhn.fhir.rest.server.interceptor;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.rest.api.Constants;
|
||||||
|
import ca.uhn.fhir.rest.server.provider.HashMapResourceProvider;
|
||||||
|
import ca.uhn.fhir.test.utilities.server.HashMapResourceProviderRule;
|
||||||
|
import ca.uhn.fhir.test.utilities.server.RestfulServerRule;
|
||||||
|
import org.hl7.fhir.r4.model.Bundle;
|
||||||
|
import org.hl7.fhir.r4.model.Patient;
|
||||||
|
import org.junit.*;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
|
||||||
|
public class CaptureResourceSourceFromHeaderInterceptorTest {
|
||||||
|
|
||||||
|
private static FhirContext ourCtx = FhirContext.forR4();
|
||||||
|
@ClassRule
|
||||||
|
public static RestfulServerRule ourServerRule = new RestfulServerRule(ourCtx);
|
||||||
|
private CaptureResourceSourceFromHeaderInterceptor myInterceptor;
|
||||||
|
@Rule
|
||||||
|
public HashMapResourceProviderRule<Patient> myPatientProviderRule = new HashMapResourceProviderRule<>(ourServerRule, Patient.class);
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void before() {
|
||||||
|
myInterceptor = new CaptureResourceSourceFromHeaderInterceptor(ourCtx);
|
||||||
|
ourServerRule.getRestfulServer().registerInterceptor(myInterceptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void after() {
|
||||||
|
ourServerRule.getRestfulServer().unregisterInterceptor(myInterceptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateWithoutAnything() {
|
||||||
|
Patient resource = new Patient();
|
||||||
|
resource.setActive(true);
|
||||||
|
|
||||||
|
ourServerRule.getFhirClient().create().resource(resource).execute();
|
||||||
|
|
||||||
|
Patient stored = myPatientProviderRule.getStoredResources().get(0);
|
||||||
|
assertNull(stored.getMeta().getSource());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateWithSource() {
|
||||||
|
Patient resource = new Patient();
|
||||||
|
resource.setActive(true);
|
||||||
|
resource.getMeta().setSource("http://source");
|
||||||
|
|
||||||
|
ourServerRule.getFhirClient().create().resource(resource).execute();
|
||||||
|
|
||||||
|
Patient stored = myPatientProviderRule.getStoredResources().get(0);
|
||||||
|
assertEquals("http://source", stored.getMeta().getSource());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateWithHeader() {
|
||||||
|
Patient resource = new Patient();
|
||||||
|
resource.setActive(true);
|
||||||
|
|
||||||
|
ourServerRule
|
||||||
|
.getFhirClient()
|
||||||
|
.create()
|
||||||
|
.resource(resource)
|
||||||
|
.withAdditionalHeader(Constants.HEADER_REQUEST_SOURCE, "http://header")
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
Patient stored = myPatientProviderRule.getStoredResources().get(0);
|
||||||
|
assertEquals("http://header", stored.getMeta().getSource());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateWithBoth() {
|
||||||
|
Patient resource = new Patient();
|
||||||
|
resource.setActive(true);
|
||||||
|
resource.getMeta().setSource("http://source");
|
||||||
|
|
||||||
|
ourServerRule
|
||||||
|
.getFhirClient()
|
||||||
|
.create()
|
||||||
|
.resource(resource)
|
||||||
|
.withAdditionalHeader(Constants.HEADER_REQUEST_SOURCE, "http://header")
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
Patient stored = myPatientProviderRule.getStoredResources().get(0);
|
||||||
|
assertEquals("http://header", stored.getMeta().getSource());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNonCreateShouldntFail() {
|
||||||
|
Bundle bundle = ourServerRule
|
||||||
|
.getFhirClient()
|
||||||
|
.search()
|
||||||
|
.forResource(Patient.class)
|
||||||
|
.returnBundle(Bundle.class)
|
||||||
|
.execute();
|
||||||
|
assertEquals(0, bundle.getEntry().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -21,6 +21,16 @@
|
||||||
<artifactId>hapi-fhir-base</artifactId>
|
<artifactId>hapi-fhir-base</artifactId>
|
||||||
<version>4.1.0-SNAPSHOT</version>
|
<version>4.1.0-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
|
<artifactId>hapi-fhir-server</artifactId>
|
||||||
|
<version>4.1.0-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
|
<artifactId>hapi-fhir-client</artifactId>
|
||||||
|
<version>4.1.0-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- General -->
|
<!-- General -->
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -53,6 +63,16 @@
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Jetty -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
<artifactId>jetty-servlet</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
<artifactId>jetty-servlet</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
package ca.uhn.fhir.test.utilities.server;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.rest.server.provider.HashMapResourceProvider;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
import org.junit.rules.TestRule;
|
||||||
|
import org.junit.runner.Description;
|
||||||
|
import org.junit.runners.model.Statement;
|
||||||
|
|
||||||
|
public class HashMapResourceProviderRule<T extends IBaseResource> extends HashMapResourceProvider<T> implements TestRule {
|
||||||
|
|
||||||
|
private final RestfulServerRule myRestfulServerRule;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param theFhirContext The FHIR context
|
||||||
|
* @param theResourceType The resource type to support
|
||||||
|
*/
|
||||||
|
public HashMapResourceProviderRule(RestfulServerRule theRestfulServerRule, Class<T> theResourceType) {
|
||||||
|
super(theRestfulServerRule.getFhirContext(), theResourceType);
|
||||||
|
|
||||||
|
myRestfulServerRule = theRestfulServerRule;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Statement apply(Statement base, Description description) {
|
||||||
|
return new Statement() {
|
||||||
|
@Override
|
||||||
|
public void evaluate() throws Throwable {
|
||||||
|
clear();
|
||||||
|
myRestfulServerRule.getRestfulServer().registerProvider(HashMapResourceProviderRule.this);
|
||||||
|
try {
|
||||||
|
base.evaluate();
|
||||||
|
} finally {
|
||||||
|
myRestfulServerRule.getRestfulServer().unregisterProvider(HashMapResourceProviderRule.this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,95 @@
|
||||||
|
package ca.uhn.fhir.test.utilities.server;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
||||||
|
import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum;
|
||||||
|
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||||
|
import ca.uhn.fhir.test.utilities.JettyUtil;
|
||||||
|
import org.apache.commons.lang3.time.DateUtils;
|
||||||
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
|
import org.apache.http.impl.client.HttpClientBuilder;
|
||||||
|
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||||
|
import org.eclipse.jetty.server.Server;
|
||||||
|
import org.eclipse.jetty.servlet.ServletHandler;
|
||||||
|
import org.eclipse.jetty.servlet.ServletHolder;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.rules.TestRule;
|
||||||
|
import org.junit.runner.Description;
|
||||||
|
import org.junit.runners.model.Statement;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
public class RestfulServerRule implements TestRule {
|
||||||
|
private static final Logger ourLog = LoggerFactory.getLogger(RestfulServerRule.class);
|
||||||
|
|
||||||
|
private final FhirContext myFhirContext;
|
||||||
|
private final Object[] myProviders;
|
||||||
|
private Server myServer;
|
||||||
|
private RestfulServer myServlet;
|
||||||
|
private int myPort;
|
||||||
|
private CloseableHttpClient myHttpClient;
|
||||||
|
private IGenericClient myFhirClient;
|
||||||
|
|
||||||
|
public RestfulServerRule(FhirContext theFhirContext, Object... theProviders) {
|
||||||
|
myFhirContext = theFhirContext;
|
||||||
|
myProviders = theProviders;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Statement apply(Statement theBase, Description theDescription) {
|
||||||
|
return new Statement() {
|
||||||
|
@Override
|
||||||
|
public void evaluate() throws Throwable {
|
||||||
|
startServer();
|
||||||
|
theBase.evaluate();
|
||||||
|
stopServer();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void stopServer() throws Exception {
|
||||||
|
JettyUtil.closeServer(myServer);
|
||||||
|
myHttpClient.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
private void startServer() throws Exception {
|
||||||
|
myServer = new Server(0);
|
||||||
|
|
||||||
|
ServletHandler servletHandler = new ServletHandler();
|
||||||
|
myServlet = new RestfulServer(myFhirContext);
|
||||||
|
myServlet.setDefaultPrettyPrint(true);
|
||||||
|
myServlet.registerProviders(myProviders);
|
||||||
|
ServletHolder servletHolder = new ServletHolder(myServlet);
|
||||||
|
servletHandler.addServletWithMapping(servletHolder, "/*");
|
||||||
|
|
||||||
|
myServer.setHandler(servletHandler);
|
||||||
|
myServer.start();
|
||||||
|
myPort = JettyUtil.getPortForStartedServer(myServer);
|
||||||
|
ourLog.info("Server has started on port {}", myPort);
|
||||||
|
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS);
|
||||||
|
HttpClientBuilder builder = HttpClientBuilder.create();
|
||||||
|
builder.setConnectionManager(connectionManager);
|
||||||
|
myHttpClient = builder.build();
|
||||||
|
|
||||||
|
myFhirContext.getRestfulClientFactory().setSocketTimeout((int) (500 * DateUtils.MILLIS_PER_SECOND));
|
||||||
|
myFhirContext.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
|
||||||
|
myFhirClient = myFhirContext.newRestfulGenericClient("http://localhost:" + myPort);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public IGenericClient getFhirClient() {
|
||||||
|
return myFhirClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FhirContext getFhirContext() {
|
||||||
|
return myFhirContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RestfulServer getRestfulServer() {
|
||||||
|
return myServlet;
|
||||||
|
}
|
||||||
|
}
|
|
@ -450,6 +450,14 @@
|
||||||
Several issues with HAPI FHIR's annotation scanner that prevented use with Kotlin based
|
Several issues with HAPI FHIR's annotation scanner that prevented use with Kotlin based
|
||||||
resource providers have been corrected. Thanks to Jelmer ter Wal for the pull request!
|
resource providers have been corrected. Thanks to Jelmer ter Wal for the pull request!
|
||||||
</action>
|
</action>
|
||||||
|
<action type="add">
|
||||||
|
A new built-in server interceptor called
|
||||||
|
<![CDATA[<code>CaptureResourceSourceFromHeaderInterceptor</code>]]>
|
||||||
|
has been added.
|
||||||
|
This interceptor can be used to capture an incoming source system URI in an HTTP Request
|
||||||
|
Header and automatically place it in
|
||||||
|
<![CDATA[<code>Resource.meta.source</code>]]>
|
||||||
|
</action>
|
||||||
</release>
|
</release>
|
||||||
<release version="4.0.3" date="2019-09-03" description="Igloo (Point Release)">
|
<release version="4.0.3" date="2019-09-03" description="Igloo (Point Release)">
|
||||||
<action type="fix">
|
<action type="fix">
|
||||||
|
|
|
@ -313,6 +313,18 @@
|
||||||
|
|
||||||
</subsection>
|
</subsection>
|
||||||
|
|
||||||
|
<subsection name="Capturing Meta.source from an HTTP Header">
|
||||||
|
|
||||||
|
<p>
|
||||||
|
If you wish to override the value of <code>Resource.meta.source</code> using the value
|
||||||
|
supplied in an HTTP header, you can use the
|
||||||
|
<a href="./apidocs/ca/uhn/fhir/rest/server/interceptor/CaptureResourceSourceFromHeaderInterceptor.html">CaptureResourceSourceFromHeaderInterceptor</a>
|
||||||
|
(<a href="./xref/ca/uhn/fhir/rest/server/interceptor/CaptureResourceSourceFromHeaderInterceptor.html">code</a>)
|
||||||
|
to accomplish this.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</subsection>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section name="Creating Interceptors">
|
<section name="Creating Interceptors">
|
||||||
|
|
Loading…
Reference in New Issue