Fix #534: Add setting for logical references to DAOConfig
Merge branch 'master' into issue534
This commit is contained in:
commit
2c9a6e65e7
|
@ -45,7 +45,7 @@ public interface ISort<T> {
|
||||||
/**
|
/**
|
||||||
* Sort descending
|
* Sort descending
|
||||||
*
|
*
|
||||||
* @param A query param - Could be a constant such as <code>Patient.ADDRESS</code> or a custom
|
* @param theParam A query param - Could be a constant such as <code>Patient.ADDRESS</code> or a custom
|
||||||
* param such as <code>new StringClientParam("foo")</code>
|
* param such as <code>new StringClientParam("foo")</code>
|
||||||
*/
|
*/
|
||||||
IQuery<T> descending(IParam theParam);
|
IQuery<T> descending(IParam theParam);
|
||||||
|
|
|
@ -187,12 +187,6 @@ public interface IServerInterceptor {
|
||||||
* A bean containing details about the request that is about to be processed, including
|
* A bean containing details about the request that is about to be processed, including
|
||||||
* @param theResponseObject
|
* @param theResponseObject
|
||||||
* The actual object which is being streamed to the client as a response
|
* The actual object which is being streamed to the client as a response
|
||||||
* @param theServletRequest
|
|
||||||
* The incoming request
|
|
||||||
* @param theServletResponse
|
|
||||||
* The response. Note that interceptors may choose to provide a response (i.e. by calling
|
|
||||||
* {@link HttpServletResponse#getWriter()}) but in that case it is important to return <code>false</code>
|
|
||||||
* to indicate that the server itself should not also provide a response.
|
|
||||||
* @return Return <code>true</code> if processing should continue normally. This is generally the right thing to do.
|
* @return Return <code>true</code> if processing should continue normally. This is generally the right thing to do.
|
||||||
* If your interceptor is providing a response rather than letting HAPI handle the response normally, you
|
* If your interceptor is providing a response rather than letting HAPI handle the response normally, you
|
||||||
* must return <code>false</code>. In this case, no further processing will occur and no further interceptors
|
* must return <code>false</code>. In this case, no further processing will occur and no further interceptors
|
||||||
|
@ -201,7 +195,7 @@ public interface IServerInterceptor {
|
||||||
* This exception may be thrown to indicate that the interceptor has detected an unauthorized access
|
* This exception may be thrown to indicate that the interceptor has detected an unauthorized access
|
||||||
* attempt. If thrown, processing will stop and an HTTP 401 will be returned to the client.
|
* attempt. If thrown, processing will stop and an HTTP 401 will be returned to the client.
|
||||||
*/
|
*/
|
||||||
boolean outgoingResponse(RequestDetails theRequest, Bundle bundle);
|
boolean outgoingResponse(RequestDetails theRequest, Bundle theResponseObject);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is called after the server implementation method has been called, but before any attempt to stream the
|
* This method is called after the server implementation method has been called, but before any attempt to stream the
|
||||||
|
|
|
@ -20,6 +20,16 @@ package ca.uhn.fhir.jpa.config;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.jpa.dao.*;
|
||||||
|
import ca.uhn.fhir.jpa.term.HapiTerminologySvcDstu2;
|
||||||
|
import ca.uhn.fhir.jpa.term.IHapiTerminologySvc;
|
||||||
|
import ca.uhn.fhir.model.dstu2.composite.MetaDt;
|
||||||
|
import ca.uhn.fhir.validation.IValidatorModule;
|
||||||
|
import org.hl7.fhir.instance.hapi.validation.DefaultProfileValidationSupport;
|
||||||
|
import org.hl7.fhir.instance.hapi.validation.FhirInstanceValidator;
|
||||||
|
import org.hl7.fhir.instance.hapi.validation.ValidationSupportChain;
|
||||||
|
import org.hl7.fhir.instance.validation.IResourceValidator.BestPracticeWarningLevel;
|
||||||
import org.springframework.beans.factory.annotation.Autowire;
|
import org.springframework.beans.factory.annotation.Autowire;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
@ -27,17 +37,6 @@ import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.context.annotation.Primary;
|
import org.springframework.context.annotation.Primary;
|
||||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
|
||||||
import ca.uhn.fhir.jpa.dao.FulltextSearchSvcImpl;
|
|
||||||
import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
|
|
||||||
import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
|
|
||||||
import ca.uhn.fhir.jpa.dao.ISearchParamRegistry;
|
|
||||||
import ca.uhn.fhir.jpa.dao.SearchParamExtractorDstu2;
|
|
||||||
import ca.uhn.fhir.jpa.dao.SearchParamRegistryDstu2;
|
|
||||||
import ca.uhn.fhir.jpa.term.HapiTerminologySvcDstu2;
|
|
||||||
import ca.uhn.fhir.jpa.term.IHapiTerminologySvc;
|
|
||||||
import ca.uhn.fhir.model.dstu2.composite.MetaDt;
|
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableTransactionManagement
|
@EnableTransactionManagement
|
||||||
public class BaseDstu2Config extends BaseConfig {
|
public class BaseDstu2Config extends BaseConfig {
|
||||||
|
@ -75,6 +74,15 @@ public class BaseDstu2Config extends BaseConfig {
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean(name = "myInstanceValidatorDstu2")
|
||||||
|
@Lazy
|
||||||
|
public IValidatorModule instanceValidatorDstu2() {
|
||||||
|
FhirInstanceValidator retVal = new FhirInstanceValidator();
|
||||||
|
retVal.setBestPracticeWarningLevel(BestPracticeWarningLevel.Warning);
|
||||||
|
retVal.setValidationSupport(new ValidationSupportChain(new DefaultProfileValidationSupport(), jpaValidationSupportDstu2()));
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
@Bean(autowire = Autowire.BY_TYPE)
|
@Bean(autowire = Autowire.BY_TYPE)
|
||||||
public IFulltextSearchSvc searchDao() {
|
public IFulltextSearchSvc searchDao() {
|
||||||
FulltextSearchSvcImpl searchDao = new FulltextSearchSvcImpl();
|
FulltextSearchSvcImpl searchDao = new FulltextSearchSvcImpl();
|
||||||
|
|
|
@ -312,29 +312,14 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<String> treatReferencesAsLogical = myConfig.getTreatReferencesAsLogical();
|
if (isLogicalReference(nextId)) {
|
||||||
if (treatReferencesAsLogical != null) {
|
ResourceLink resourceLink = new ResourceLink(nextPathAndRef.getPath(), theEntity, nextId, theUpdateTime);
|
||||||
boolean isLogical = false;
|
if (theLinks.add(resourceLink)) {
|
||||||
for (String nextLogicalRef : treatReferencesAsLogical) {
|
ourLog.info("Indexing remote resource reference URL: {}", nextId);
|
||||||
nextLogicalRef = trim(nextLogicalRef);
|
|
||||||
if (nextLogicalRef.charAt(nextLogicalRef.length() - 1) == '*') {
|
|
||||||
if (nextId.getValue().startsWith(nextLogicalRef.substring(0, nextLogicalRef.length() -1))) {
|
|
||||||
isLogical = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (nextId.getValue().equals(nextLogicalRef)) {
|
|
||||||
isLogical = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isLogical) {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
String baseUrl = nextId.getBaseUrl();
|
String baseUrl = nextId.getBaseUrl();
|
||||||
String typeString = nextId.getResourceType();
|
String typeString = nextId.getResourceType();
|
||||||
if (isBlank(typeString)) {
|
if (isBlank(typeString)) {
|
||||||
|
@ -412,6 +397,26 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected boolean isLogicalReference(IIdType theId) {
|
||||||
|
Set<String> treatReferencesAsLogical = myConfig.getTreatReferencesAsLogical();
|
||||||
|
if (treatReferencesAsLogical != null) {
|
||||||
|
for (String nextLogicalRef : treatReferencesAsLogical) {
|
||||||
|
nextLogicalRef = trim(nextLogicalRef);
|
||||||
|
if (nextLogicalRef.charAt(nextLogicalRef.length() - 1) == '*') {
|
||||||
|
if (theId.getValue().startsWith(nextLogicalRef.substring(0, nextLogicalRef.length() - 1))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (theId.getValue().equals(nextLogicalRef)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
@ -959,12 +964,11 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
||||||
* Subclasses may override to provide behaviour. Called when a resource has been inserted into the database for the first time.
|
* Subclasses may override to provide behaviour. Called when a resource has been inserted into the database for the first time.
|
||||||
*
|
*
|
||||||
* @param theEntity
|
* @param theEntity
|
||||||
* The entity being updated (Do not modify the entity! Undefined behaviour will occur!)
|
* The entity being updated (Do not modify the entity! Undefined behaviour will occur!)
|
||||||
* @param theTag
|
* @param theTag
|
||||||
* The tag
|
* The tag
|
||||||
* @return Returns <code>true</code> if the tag should be removed
|
* @return Returns <code>true</code> if the tag should be removed
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unused")
|
|
||||||
protected void postPersist(ResourceTable theEntity, T theResource) {
|
protected void postPersist(ResourceTable theEntity, T theResource) {
|
||||||
// nothing
|
// nothing
|
||||||
}
|
}
|
||||||
|
@ -973,9 +977,9 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
||||||
* Subclasses may override to provide behaviour. Called when a pre-existing resource has been updated in the database
|
* Subclasses may override to provide behaviour. Called when a pre-existing resource has been updated in the database
|
||||||
*
|
*
|
||||||
* @param theEntity
|
* @param theEntity
|
||||||
* The resource
|
* The resource
|
||||||
* @param theResource
|
* @param theResource
|
||||||
* The resource being persisted
|
* The resource being persisted
|
||||||
*/
|
*/
|
||||||
protected void postUpdate(ResourceTable theEntity, T theResource) {
|
protected void postUpdate(ResourceTable theEntity, T theResource) {
|
||||||
// nothing
|
// nothing
|
||||||
|
@ -998,7 +1002,6 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
||||||
return ids;
|
return ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
@CoverageIgnore
|
@CoverageIgnore
|
||||||
public BaseHasResource readEntity(IIdType theValueId) {
|
public BaseHasResource readEntity(IIdType theValueId) {
|
||||||
throw new NotImplementedException("");
|
throw new NotImplementedException("");
|
||||||
|
@ -1031,9 +1034,9 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param theEntity
|
* @param theEntity
|
||||||
* The entity being updated (Do not modify the entity! Undefined behaviour will occur!)
|
* The entity being updated (Do not modify the entity! Undefined behaviour will occur!)
|
||||||
* @param theTag
|
* @param theTag
|
||||||
* The tag
|
* The tag
|
||||||
* @return Retturns <code>true</code> if the tag should be removed
|
* @return Retturns <code>true</code> if the tag should be removed
|
||||||
*/
|
*/
|
||||||
protected boolean shouldDroppedTagBeRemovedOnUpdate(ResourceTable theEntity, ResourceTag theTag) {
|
protected boolean shouldDroppedTagBeRemovedOnUpdate(ResourceTable theEntity, ResourceTag theTag) {
|
||||||
|
@ -1269,7 +1272,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
||||||
setUpdatedTime(uriParams, theUpdateTime);
|
setUpdatedTime(uriParams, theUpdateTime);
|
||||||
setUpdatedTime(coordsParams, theUpdateTime);
|
setUpdatedTime(coordsParams, theUpdateTime);
|
||||||
setUpdatedTime(tokenParams, theUpdateTime);
|
setUpdatedTime(tokenParams, theUpdateTime);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handle references within the resource that are match URLs, for example references like "Patient?identifier=foo". These match URLs are resolved and replaced with the ID of the
|
* Handle references within the resource that are match URLs, for example references like "Patient?identifier=foo". These match URLs are resolved and replaced with the ID of the
|
||||||
* matching
|
* matching
|
||||||
|
@ -1531,11 +1534,14 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
||||||
|
|
||||||
for (IBase nextChild : values) {
|
for (IBase nextChild : values) {
|
||||||
IBaseReference nextRef = (IBaseReference) nextChild;
|
IBaseReference nextRef = (IBaseReference) nextChild;
|
||||||
if (!isBlank(nextRef.getReferenceElement().getResourceType())) {
|
IIdType referencedId = nextRef.getReferenceElement();
|
||||||
if (!nextRef.getReferenceElement().getValue().contains("?")) {
|
if (!isBlank(referencedId.getResourceType())) {
|
||||||
if (!validTypes.contains(nextRef.getReferenceElement().getResourceType())) {
|
if (!isLogicalReference(referencedId)) {
|
||||||
throw new UnprocessableEntityException(
|
if (!referencedId.getValue().contains("?")) {
|
||||||
"Invalid reference found at path '" + newPath + "'. Resource type '" + nextRef.getReferenceElement().getResourceType() + "' is not valid for this path");
|
if (!validTypes.contains(referencedId.getResourceType())) {
|
||||||
|
throw new UnprocessableEntityException(
|
||||||
|
"Invalid reference found at path '" + newPath + "'. Resource type '" + referencedId.getResourceType() + "' is not valid for this path");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1575,9 +1581,9 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
||||||
* "subsetted" tag and rejects resources which have it. Subclasses should call the superclass implementation to preserve this check.
|
* "subsetted" tag and rejects resources which have it. Subclasses should call the superclass implementation to preserve this check.
|
||||||
*
|
*
|
||||||
* @param theResource
|
* @param theResource
|
||||||
* The resource that is about to be persisted
|
* The resource that is about to be persisted
|
||||||
* @param theEntityToSave
|
* @param theEntityToSave
|
||||||
* TODO
|
* TODO
|
||||||
*/
|
*/
|
||||||
protected void validateResourceForStorage(T theResource, ResourceTable theEntityToSave) {
|
protected void validateResourceForStorage(T theResource, ResourceTable theEntityToSave) {
|
||||||
Object tag = null;
|
Object tag = null;
|
||||||
|
|
|
@ -56,7 +56,8 @@ public class DaoConfig {
|
||||||
// ***
|
// ***
|
||||||
// update setter javadoc if default changes
|
// update setter javadoc if default changes
|
||||||
// ***
|
// ***
|
||||||
private boolean myAllowInlineMatchUrlReferences = false;
|
private boolean myAllowInlineMatchUrlReferences = true;
|
||||||
|
|
||||||
private boolean myAllowMultipleDelete;
|
private boolean myAllowMultipleDelete;
|
||||||
private boolean myDefaultSearchParamsCanBeOverridden = false;
|
private boolean myDefaultSearchParamsCanBeOverridden = false;
|
||||||
// ***
|
// ***
|
||||||
|
@ -93,6 +94,20 @@ public class DaoConfig {
|
||||||
private Set<String> myTreatBaseUrlsAsLocal = new HashSet<String>();
|
private Set<String> myTreatBaseUrlsAsLocal = new HashSet<String>();
|
||||||
private Set<String> myTreatReferencesAsLogical = new HashSet<String>(DEFAULT_LOGICAL_BASE_URLS);
|
private Set<String> myTreatReferencesAsLogical = new HashSet<String>(DEFAULT_LOGICAL_BASE_URLS);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a value to the {@link #setTreatReferencesAsLogical(Set) logical references list}.
|
||||||
|
*
|
||||||
|
* @see #setTreatReferencesAsLogical(Set)
|
||||||
|
*/
|
||||||
|
public void addTreatReferencesAsLogical(String theTreatReferencesAsLogical) {
|
||||||
|
validateTreatBaseUrlsAsLocal(theTreatReferencesAsLogical);
|
||||||
|
|
||||||
|
if (myTreatReferencesAsLogical == null) {
|
||||||
|
myTreatReferencesAsLogical = new HashSet<String>();
|
||||||
|
}
|
||||||
|
myTreatReferencesAsLogical.add(theTreatReferencesAsLogical);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When a code system is added that contains more than this number of codes,
|
* When a code system is added that contains more than this number of codes,
|
||||||
* the code system will be indexed later in an incremental process in order to
|
* the code system will be indexed later in an incremental process in order to
|
||||||
|
@ -115,9 +130,9 @@ public class DaoConfig {
|
||||||
* (next/prev links in search response bundles) will become invalid. Defaults to 1 hour.
|
* (next/prev links in search response bundles) will become invalid. Defaults to 1 hour.
|
||||||
* </p>
|
* </p>
|
||||||
* <p>
|
* <p>
|
||||||
*
|
* <p>
|
||||||
* @see To disable this feature entirely, see {@link #setExpireSearchResults(boolean)}
|
* To disable this feature entirely, see {@link #setExpireSearchResults(boolean)}
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
|
@ -196,9 +211,9 @@ public class DaoConfig {
|
||||||
* references instead of being treated as real references.
|
* references instead of being treated as real references.
|
||||||
* <p>
|
* <p>
|
||||||
* A logical reference is a reference which is treated as an identifier, and
|
* A logical reference is a reference which is treated as an identifier, and
|
||||||
* does not neccesarily resolve. See {@link http://hl7.org/fhir/references.html} for
|
* does not neccesarily resolve. See {@link "http://hl7.org/fhir/references.html"} for
|
||||||
* a description of logical references. For example, the valueset
|
* a description of logical references. For example, the valueset
|
||||||
* {@link http://hl7.org/fhir/valueset-quantity-comparator.html} is a logical
|
* {@link "http://hl7.org/fhir/valueset-quantity-comparator.html"} is a logical
|
||||||
* reference.
|
* reference.
|
||||||
* </p>
|
* </p>
|
||||||
* <p>
|
* <p>
|
||||||
|
@ -209,7 +224,7 @@ public class DaoConfig {
|
||||||
* <li><code>http://example.com/some-base*</code> <b>(will match anything beginning with the part before the *)</b></li>
|
* <li><code>http://example.com/some-base*</code> <b>(will match anything beginning with the part before the *)</b></li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* @see #DEFAULT_LOGICAL_BASE_URLS for a list of default values for this setting
|
* @see #DEFAULT_LOGICAL_BASE_URLS Default values for this property
|
||||||
*/
|
*/
|
||||||
public Set<String> getTreatReferencesAsLogical() {
|
public Set<String> getTreatReferencesAsLogical() {
|
||||||
return myTreatReferencesAsLogical;
|
return myTreatReferencesAsLogical;
|
||||||
|
@ -337,7 +352,9 @@ public class DaoConfig {
|
||||||
* to "Patient?identifier=12345", this is reference match URL will be resolved and replaced according
|
* to "Patient?identifier=12345", this is reference match URL will be resolved and replaced according
|
||||||
* to the usual match URL rules.
|
* to the usual match URL rules.
|
||||||
* <p>
|
* <p>
|
||||||
* Default is false for now, as this is an experimental feature.
|
* Default is {@literal true} beginning in HAPI FHIR 2.4, since this
|
||||||
|
* feature is now specified in the FHIR specification. (Previously it
|
||||||
|
* was an experimental/rpposed feature)
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
|
@ -401,8 +418,10 @@ public class DaoConfig {
|
||||||
* </p>
|
* </p>
|
||||||
* <p>
|
* <p>
|
||||||
*
|
*
|
||||||
* @see To disable this feature entirely, see {@link #setExpireSearchResults(boolean)}
|
* <p>
|
||||||
* </p>
|
* To disable this feature entirely, see {@link #setExpireSearchResults(boolean)}
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public void setExpireSearchResultsAfterMillis(long theExpireSearchResultsAfterMillis) {
|
public void setExpireSearchResultsAfterMillis(long theExpireSearchResultsAfterMillis) {
|
||||||
|
@ -418,7 +437,7 @@ public class DaoConfig {
|
||||||
* paging provider instead. Deprecated in HAPI FHIR 2.3 (Jan 2017)
|
* paging provider instead. Deprecated in HAPI FHIR 2.3 (Jan 2017)
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public void setHardSearchLimit(@SuppressWarnings("unused") int theHardSearchLimit) {
|
public void setHardSearchLimit(int theHardSearchLimit) {
|
||||||
// this method does nothing
|
// this method does nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -528,6 +547,12 @@ public class DaoConfig {
|
||||||
* means no references will be treated as external
|
* means no references will be treated as external
|
||||||
*/
|
*/
|
||||||
public void setTreatBaseUrlsAsLocal(Set<String> theTreatBaseUrlsAsLocal) {
|
public void setTreatBaseUrlsAsLocal(Set<String> theTreatBaseUrlsAsLocal) {
|
||||||
|
if (theTreatBaseUrlsAsLocal != null) {
|
||||||
|
for (String next : theTreatBaseUrlsAsLocal) {
|
||||||
|
validateTreatBaseUrlsAsLocal(next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
HashSet<String> treatBaseUrlsAsLocal = new HashSet<String>();
|
HashSet<String> treatBaseUrlsAsLocal = new HashSet<String>();
|
||||||
for (String next : ObjectUtils.defaultIfNull(theTreatBaseUrlsAsLocal, new HashSet<String>())) {
|
for (String next : ObjectUtils.defaultIfNull(theTreatBaseUrlsAsLocal, new HashSet<String>())) {
|
||||||
while (next.endsWith("/")) {
|
while (next.endsWith("/")) {
|
||||||
|
@ -544,9 +569,9 @@ public class DaoConfig {
|
||||||
* references instead of being treated as real references.
|
* references instead of being treated as real references.
|
||||||
* <p>
|
* <p>
|
||||||
* A logical reference is a reference which is treated as an identifier, and
|
* A logical reference is a reference which is treated as an identifier, and
|
||||||
* does not neccesarily resolve. See {@link http://hl7.org/fhir/references.html} for
|
* does not neccesarily resolve. See {@link "http://hl7.org/fhir/references.html"} for
|
||||||
* a description of logical references. For example, the valueset
|
* a description of logical references. For example, the valueset
|
||||||
* {@link http://hl7.org/fhir/valueset-quantity-comparator.html} is a logical
|
* {@link "http://hl7.org/fhir/valueset-quantity-comparator.html"} is a logical
|
||||||
* reference.
|
* reference.
|
||||||
* </p>
|
* </p>
|
||||||
* <p>
|
* <p>
|
||||||
|
@ -557,11 +582,23 @@ public class DaoConfig {
|
||||||
* <li><code>http://example.com/some-base*</code> <b>(will match anything beginning with the part before the *)</b></li>
|
* <li><code>http://example.com/some-base*</code> <b>(will match anything beginning with the part before the *)</b></li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* @see #DEFAULT_LOGICAL_BASE_URLS for a list of default values for this setting
|
* @see #DEFAULT_LOGICAL_BASE_URLS Default values for this property
|
||||||
*/
|
*/
|
||||||
public DaoConfig setTreatReferencesAsLogical(Set<String> theTreatReferencesAsLogical) {
|
public DaoConfig setTreatReferencesAsLogical(Set<String> theTreatReferencesAsLogical) {
|
||||||
myTreatReferencesAsLogical = theTreatReferencesAsLogical;
|
myTreatReferencesAsLogical = theTreatReferencesAsLogical;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void validateTreatBaseUrlsAsLocal(String theUrl) {
|
||||||
|
Validate.notBlank(theUrl, "Base URL must not be null or empty");
|
||||||
|
|
||||||
|
int starIdx = theUrl.indexOf('*');
|
||||||
|
if (starIdx != -1) {
|
||||||
|
if (starIdx != theUrl.length() - 1) {
|
||||||
|
throw new IllegalArgumentException("Base URL wildcard character (*) can only appear at the end of the string: " + theUrl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,43 +1,5 @@
|
||||||
package ca.uhn.fhir.jpa.dao;
|
package ca.uhn.fhir.jpa.dao;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* #%L
|
|
||||||
* HAPI FHIR JPA Server
|
|
||||||
* %%
|
|
||||||
* Copyright (C) 2014 - 2017 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 java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.hl7.fhir.instance.hapi.validation.DefaultProfileValidationSupport;
|
|
||||||
import org.hl7.fhir.instance.hapi.validation.FhirInstanceValidator;
|
|
||||||
import org.hl7.fhir.instance.hapi.validation.IValidationSupport;
|
|
||||||
import org.hl7.fhir.instance.hapi.validation.ValidationSupportChain;
|
|
||||||
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
|
||||||
import org.hl7.fhir.instance.validation.IResourceValidator.BestPracticeWarningLevel;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
|
||||||
|
|
||||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||||
import ca.uhn.fhir.context.RuntimeSearchParam;
|
import ca.uhn.fhir.context.RuntimeSearchParam;
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceTable;
|
import ca.uhn.fhir.jpa.entity.ResourceTable;
|
||||||
|
@ -64,6 +26,38 @@ import ca.uhn.fhir.validation.FhirValidator;
|
||||||
import ca.uhn.fhir.validation.IValidationContext;
|
import ca.uhn.fhir.validation.IValidationContext;
|
||||||
import ca.uhn.fhir.validation.IValidatorModule;
|
import ca.uhn.fhir.validation.IValidatorModule;
|
||||||
import ca.uhn.fhir.validation.ValidationResult;
|
import ca.uhn.fhir.validation.ValidationResult;
|
||||||
|
import org.hl7.fhir.instance.hapi.validation.IValidationSupport;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* HAPI FHIR JPA Server
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2014 - 2017 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%
|
||||||
|
*/
|
||||||
|
|
||||||
public class FhirResourceDaoDstu2<T extends IResource> extends BaseHapiFhirResourceDao<T> {
|
public class FhirResourceDaoDstu2<T extends IResource> extends BaseHapiFhirResourceDao<T> {
|
||||||
|
|
||||||
|
@ -71,6 +65,9 @@ public class FhirResourceDaoDstu2<T extends IResource> extends BaseHapiFhirResou
|
||||||
@Qualifier("myJpaValidationSupportDstu2")
|
@Qualifier("myJpaValidationSupportDstu2")
|
||||||
private IValidationSupport myJpaValidationSupport;
|
private IValidationSupport myJpaValidationSupport;
|
||||||
|
|
||||||
|
@Autowired()
|
||||||
|
@Qualifier("myInstanceValidatorDstu2")
|
||||||
|
private IValidatorModule myInstanceValidator;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<Object> getIncludeValues(FhirTerser theTerser, Include theInclude, IBaseResource theResource, RuntimeResourceDefinition theResourceDef) {
|
protected List<Object> getIncludeValues(FhirTerser theTerser, Include theInclude, IBaseResource theResource, RuntimeResourceDefinition theResourceDef) {
|
||||||
|
@ -124,10 +121,7 @@ public class FhirResourceDaoDstu2<T extends IResource> extends BaseHapiFhirResou
|
||||||
|
|
||||||
FhirValidator validator = getContext().newValidator();
|
FhirValidator validator = getContext().newValidator();
|
||||||
|
|
||||||
FhirInstanceValidator val = new FhirInstanceValidator();
|
validator.registerValidatorModule(myInstanceValidator);
|
||||||
val.setBestPracticeWarningLevel(BestPracticeWarningLevel.Warning);
|
|
||||||
val.setValidationSupport(new ValidationSupportChain(new DefaultProfileValidationSupport(), myJpaValidationSupport));
|
|
||||||
validator.registerValidatorModule(val);
|
|
||||||
|
|
||||||
validator.registerValidatorModule(new IdChecker(theMode));
|
validator.registerValidatorModule(new IdChecker(theMode));
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,20 @@
|
||||||
package ca.uhn.fhir.jpa.config;
|
package ca.uhn.fhir.jpa.config;
|
||||||
|
|
||||||
import java.util.Properties;
|
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
||||||
|
import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor;
|
||||||
import javax.persistence.EntityManagerFactory;
|
import ca.uhn.fhir.validation.ResultSeverityEnum;
|
||||||
import javax.sql.DataSource;
|
|
||||||
|
|
||||||
import org.apache.commons.dbcp2.BasicDataSource;
|
import org.apache.commons.dbcp2.BasicDataSource;
|
||||||
import org.hibernate.jpa.HibernatePersistenceProvider;
|
import org.hibernate.jpa.HibernatePersistenceProvider;
|
||||||
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.Primary;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.orm.jpa.JpaTransactionManager;
|
import org.springframework.orm.jpa.JpaTransactionManager;
|
||||||
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import javax.persistence.EntityManagerFactory;
|
||||||
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
import javax.sql.DataSource;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableTransactionManagement()
|
@EnableTransactionManagement()
|
||||||
|
@ -65,4 +64,19 @@ public class TestDstu2Config extends BaseJavaConfigDstu2 {
|
||||||
return extraProperties;
|
return extraProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bean which validates incoming requests
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
@Lazy
|
||||||
|
public RequestValidatingInterceptor requestValidatingInterceptor() {
|
||||||
|
RequestValidatingInterceptor requestValidator = new RequestValidatingInterceptor();
|
||||||
|
requestValidator.setFailOnSeverity(ResultSeverityEnum.ERROR);
|
||||||
|
requestValidator.setAddResponseHeaderOnSeverity(null);
|
||||||
|
requestValidator.setAddResponseOutcomeHeaderOnSeverity(ResultSeverityEnum.INFORMATION);
|
||||||
|
requestValidator.addValidatorModule(instanceValidatorDstu2());
|
||||||
|
|
||||||
|
return requestValidator;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
package ca.uhn.fhir.jpa.dao;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class DaoConfigTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidLogicalPattern() {
|
||||||
|
new DaoConfig().setTreatBaseUrlsAsLocal(new HashSet<String>(Arrays.asList("http://foo")));
|
||||||
|
new DaoConfig().setTreatBaseUrlsAsLocal(new HashSet<String>(Arrays.asList("http://foo*")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInvalidLogicalPattern() {
|
||||||
|
try {
|
||||||
|
new DaoConfig().setTreatBaseUrlsAsLocal(new HashSet<String>(Arrays.asList("http://*foo")));
|
||||||
|
fail();
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
assertEquals("Base URL wildcard character (*) can only appear at the end of the string: http://*foo", e.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
new DaoConfig().setTreatBaseUrlsAsLocal(new HashSet<String>(Arrays.asList("http://foo**")));
|
||||||
|
fail();
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
assertEquals("Base URL wildcard character (*) can only appear at the end of the string: http://foo**", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -65,28 +65,12 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
||||||
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoDstu2Test.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoDstu2Test.class);
|
||||||
|
|
||||||
@AfterClass
|
@After
|
||||||
public static void afterClassClearContext() {
|
public final void after() {
|
||||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
myDaoConfig.setAllowExternalReferences(new DaoConfig().isAllowExternalReferences());
|
||||||
|
myDaoConfig.setTreatReferencesAsLogical(new DaoConfig().getTreatReferencesAsLogical());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* See #534
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testBuiltInLogicalReferences() throws IOException {
|
|
||||||
myDaoConfig.getTreatReferencesAsLogical().add("http://phr.kanta.fi/fiphr-vs-*");
|
|
||||||
|
|
||||||
ValueSet vsBodySite = loadResourceFromClasspath(ValueSet.class, "/issue534/fiphr-vs-bodysite.xml");
|
|
||||||
myValueSetDao.create(vsBodySite, mySrd);
|
|
||||||
ValueSet vsObsMethod = loadResourceFromClasspath(ValueSet.class, "/issue534/fiphr-vs-observationmethod.xml");
|
|
||||||
myValueSetDao.create(vsObsMethod, mySrd);
|
|
||||||
|
|
||||||
StructureDefinition sd = loadResourceFromClasspath(StructureDefinition.class, "/issue534/bw_profile_snapshot.xml");
|
|
||||||
myStructureDefinitionDao.create(sd, mySrd);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void assertGone(IIdType theId) {
|
private void assertGone(IIdType theId) {
|
||||||
try {
|
try {
|
||||||
assertNotGone(theId);
|
assertNotGone(theId);
|
||||||
|
@ -96,82 +80,13 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
|
||||||
public final void after() {
|
|
||||||
myDaoConfig.setAllowExternalReferences(new DaoConfig().isAllowExternalReferences());
|
|
||||||
myDaoConfig.setTreatReferencesAsLogical(new DaoConfig().getTreatReferencesAsLogical());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testValidateAgainstDstu2Profile() throws Exception {
|
|
||||||
myDaoConfig.setAllowExternalReferences(true);
|
|
||||||
|
|
||||||
String stream = IOUtils.toString(getClass().getResourceAsStream("/binu_testpatient_structuredefinition_dstu2.xml"), StandardCharsets.UTF_8);
|
|
||||||
|
|
||||||
StructureDefinition sd = myFhirCtx.newXmlParser().parseResource(StructureDefinition.class, stream);
|
|
||||||
myStructureDefinitionDao.create(sd, mySrd);
|
|
||||||
|
|
||||||
String rawResource = IOUtils.toString(getClass().getResourceAsStream("/binu_testpatient_resource.json"), StandardCharsets.UTF_8);
|
|
||||||
try {
|
|
||||||
myValueSetDao.validate(null, null, rawResource, EncodingEnum.JSON, ValidationModeEnum.UPDATE, null, mySrd);
|
|
||||||
fail();
|
|
||||||
} catch (PreconditionFailedException e) {
|
|
||||||
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(e.getOperationOutcome()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCreateBundleAllowsDocumentAndCollection() {
|
|
||||||
String methodName = "testCreateBundleAllowsDocumentAndCollection";
|
|
||||||
|
|
||||||
Patient p = new Patient();
|
|
||||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
|
||||||
IIdType pid = myPatientDao.create(p, mySrd).getId();
|
|
||||||
p.setId(pid);
|
|
||||||
ourLog.info("Created patient, got it: {}", pid);
|
|
||||||
|
|
||||||
Bundle bundle = new Bundle();
|
|
||||||
bundle.setType((BundleTypeEnum)null);
|
|
||||||
bundle.addEntry().setResource(p).setFullUrl(pid.toUnqualifiedVersionless().getValue());
|
|
||||||
try {
|
|
||||||
myBundleDao.create(bundle, mySrd);
|
|
||||||
fail();
|
|
||||||
} catch (UnprocessableEntityException e) {
|
|
||||||
assertEquals("Unable to store a Bundle resource on this server with a Bundle.type of: (missing)", e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
bundle = new Bundle();
|
|
||||||
bundle.setType(BundleTypeEnum.BATCH_RESPONSE);
|
|
||||||
bundle.addEntry().setResource(p).setFullUrl(pid.toUnqualifiedVersionless().getValue());
|
|
||||||
try {
|
|
||||||
myBundleDao.create(bundle, mySrd);
|
|
||||||
fail();
|
|
||||||
} catch (UnprocessableEntityException e) {
|
|
||||||
assertEquals("Unable to store a Bundle resource on this server with a Bundle.type of: batch-response", e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
bundle = new Bundle();
|
|
||||||
bundle.setType(BundleTypeEnum.COLLECTION);
|
|
||||||
bundle.addEntry().setResource(p).setFullUrl(pid.toUnqualifiedVersionless().getValue());
|
|
||||||
myBundleDao.create(bundle, mySrd);
|
|
||||||
|
|
||||||
bundle = new Bundle();
|
|
||||||
bundle.setType(BundleTypeEnum.DOCUMENT);
|
|
||||||
bundle.addEntry().setResource(p).setFullUrl(pid.toUnqualifiedVersionless().getValue());
|
|
||||||
myBundleDao.create(bundle, mySrd);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This gets called from assertGone too! Careful about exceptions...
|
* This gets called from assertGone too! Careful about exceptions...
|
||||||
*/
|
*/
|
||||||
private void assertNotGone(IIdType theId) {
|
private void assertNotGone(IIdType theId) {
|
||||||
if ("Patient".equals(theId.getResourceType())) {
|
if ("Patient".equals(theId.getResourceType())) {
|
||||||
myPatientDao.read(theId, mySrd);
|
myPatientDao.read(theId, mySrd);
|
||||||
} else if ("Organization".equals(theId.getResourceType())){
|
} else if ("Organization".equals(theId.getResourceType())) {
|
||||||
myOrganizationDao.read(theId, mySrd);
|
myOrganizationDao.read(theId, mySrd);
|
||||||
} else {
|
} else {
|
||||||
fail("No type");
|
fail("No type");
|
||||||
|
@ -188,7 +103,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String log(IBundleProvider theHistory) {
|
private String log(IBundleProvider theHistory) {
|
||||||
StringBuilder b =new StringBuilder(theHistory.size() + " results: ");
|
StringBuilder b = new StringBuilder(theHistory.size() + " results: ");
|
||||||
for (IBaseResource next : theHistory.getResources(0, theHistory.size())) {
|
for (IBaseResource next : theHistory.getResources(0, theHistory.size())) {
|
||||||
b.append("\n ").append(next.getIdElement().toUnqualified().getValue());
|
b.append("\n ").append(next.getIdElement().toUnqualified().getValue());
|
||||||
}
|
}
|
||||||
|
@ -233,6 +148,23 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See #534
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testBuiltInLogicalReferences() throws IOException {
|
||||||
|
myDaoConfig.getTreatReferencesAsLogical().add("http://phr.kanta.fi/fiphr-vs-*");
|
||||||
|
|
||||||
|
ValueSet vsBodySite = loadResourceFromClasspath(ValueSet.class, "/issue534/fiphr-vs-bodysite.xml");
|
||||||
|
myValueSetDao.create(vsBodySite, mySrd);
|
||||||
|
ValueSet vsObsMethod = loadResourceFromClasspath(ValueSet.class, "/issue534/fiphr-vs-observationmethod.xml");
|
||||||
|
myValueSetDao.create(vsObsMethod, mySrd);
|
||||||
|
|
||||||
|
// Just make sure this saves
|
||||||
|
StructureDefinition sd = loadResourceFromClasspath(StructureDefinition.class, "/issue534/bw_profile_snapshot.xml");
|
||||||
|
myStructureDefinitionDao.create(sd, mySrd);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCantSearchForDeletedResourceByLanguageOrTag() {
|
public void testCantSearchForDeletedResourceByLanguageOrTag() {
|
||||||
String methodName = "testCantSearchForDeletedResourceByLanguageOrTag";
|
String methodName = "testCantSearchForDeletedResourceByLanguageOrTag";
|
||||||
|
@ -384,6 +316,48 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateBundleAllowsDocumentAndCollection() {
|
||||||
|
String methodName = "testCreateBundleAllowsDocumentAndCollection";
|
||||||
|
|
||||||
|
Patient p = new Patient();
|
||||||
|
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||||
|
IIdType pid = myPatientDao.create(p, mySrd).getId();
|
||||||
|
p.setId(pid);
|
||||||
|
ourLog.info("Created patient, got it: {}", pid);
|
||||||
|
|
||||||
|
Bundle bundle = new Bundle();
|
||||||
|
bundle.setType((BundleTypeEnum) null);
|
||||||
|
bundle.addEntry().setResource(p).setFullUrl(pid.toUnqualifiedVersionless().getValue());
|
||||||
|
try {
|
||||||
|
myBundleDao.create(bundle, mySrd);
|
||||||
|
fail();
|
||||||
|
} catch (UnprocessableEntityException e) {
|
||||||
|
assertEquals("Unable to store a Bundle resource on this server with a Bundle.type of: (missing)", e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
bundle = new Bundle();
|
||||||
|
bundle.setType(BundleTypeEnum.BATCH_RESPONSE);
|
||||||
|
bundle.addEntry().setResource(p).setFullUrl(pid.toUnqualifiedVersionless().getValue());
|
||||||
|
try {
|
||||||
|
myBundleDao.create(bundle, mySrd);
|
||||||
|
fail();
|
||||||
|
} catch (UnprocessableEntityException e) {
|
||||||
|
assertEquals("Unable to store a Bundle resource on this server with a Bundle.type of: batch-response", e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
bundle = new Bundle();
|
||||||
|
bundle.setType(BundleTypeEnum.COLLECTION);
|
||||||
|
bundle.addEntry().setResource(p).setFullUrl(pid.toUnqualifiedVersionless().getValue());
|
||||||
|
myBundleDao.create(bundle, mySrd);
|
||||||
|
|
||||||
|
bundle = new Bundle();
|
||||||
|
bundle.setType(BundleTypeEnum.DOCUMENT);
|
||||||
|
bundle.addEntry().setResource(p).setFullUrl(pid.toUnqualifiedVersionless().getValue());
|
||||||
|
myBundleDao.create(bundle, mySrd);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateOperationOutcome() {
|
public void testCreateOperationOutcome() {
|
||||||
/*
|
/*
|
||||||
|
@ -818,8 +792,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
||||||
assertThat(found, empty());
|
assertThat(found, empty());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDeleteResource() {
|
public void testDeleteResource() {
|
||||||
int initialHistory = myPatientDao.history(null, null, mySrd).size();
|
int initialHistory = myPatientDao.history(null, null, mySrd).size();
|
||||||
|
@ -882,7 +855,6 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
||||||
assertEquals(0, patients.size());
|
assertEquals(0, patients.size());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDeleteThenUndelete() {
|
public void testDeleteThenUndelete() {
|
||||||
|
@ -917,7 +889,6 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
||||||
assertEquals(id2, gotId);
|
assertEquals(id2, gotId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDeleteWithMatchUrl() {
|
public void testDeleteWithMatchUrl() {
|
||||||
String methodName = "testDeleteWithMatchUrl";
|
String methodName = "testDeleteWithMatchUrl";
|
||||||
|
@ -974,23 +945,24 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
||||||
myPatientDao.deleteByUrl("Patient?organization.identifier=http://example.com|" + methodName, mySrd);
|
myPatientDao.deleteByUrl("Patient?organization.identifier=http://example.com|" + methodName, mySrd);
|
||||||
assertGone(id);
|
assertGone(id);
|
||||||
assertNotGone(orgId);
|
assertNotGone(orgId);
|
||||||
|
|
||||||
myOrganizationDao.deleteByUrl("Organization?identifier=http://example.com|" + methodName, mySrd);
|
myOrganizationDao.deleteByUrl("Organization?identifier=http://example.com|" + methodName, mySrd);
|
||||||
assertGone(id);
|
assertGone(id);
|
||||||
assertGone(orgId);
|
assertGone(orgId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDeleteWithMatchUrlChainedProfile() {
|
public void testDeleteWithMatchUrlChainedProfile() {
|
||||||
String methodName = "testDeleteWithMatchUrlChainedProfile";
|
String methodName = "testDeleteWithMatchUrlChainedProfile";
|
||||||
|
|
||||||
List<IdDt> profileList = new ArrayList<IdDt>();
|
List<IdDt> profileList = new ArrayList<IdDt>();
|
||||||
profileList.add(new IdDt("http://foo"));
|
profileList.add(new IdDt("http://foo"));
|
||||||
|
|
||||||
Organization org = new Organization();
|
Organization org = new Organization();
|
||||||
ResourceMetadataKeyEnum.PROFILES.put(org, profileList);
|
ResourceMetadataKeyEnum.PROFILES.put(org, profileList);
|
||||||
org.setName(methodName);
|
org.setName(methodName);
|
||||||
|
|
||||||
IIdType orgId = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless();
|
IIdType orgId = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
|
@ -1002,7 +974,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
||||||
|
|
||||||
myPatientDao.deleteByUrl("Patient?organization._profile=http://foo", mySrd);
|
myPatientDao.deleteByUrl("Patient?organization._profile=http://foo", mySrd);
|
||||||
assertGone(id);
|
assertGone(id);
|
||||||
|
|
||||||
myOrganizationDao.deleteByUrl("Organization?_profile=http://foo", mySrd);
|
myOrganizationDao.deleteByUrl("Organization?_profile=http://foo", mySrd);
|
||||||
try {
|
try {
|
||||||
myOrganizationDao.read(orgId, mySrd);
|
myOrganizationDao.read(orgId, mySrd);
|
||||||
|
@ -1027,8 +999,6 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDeleteWithMatchUrlChainedString() {
|
public void testDeleteWithMatchUrlChainedString() {
|
||||||
String methodName = "testDeleteWithMatchUrlChainedString";
|
String methodName = "testDeleteWithMatchUrlChainedString";
|
||||||
|
@ -1055,11 +1025,11 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
||||||
|
|
||||||
TagList tl = new TagList();
|
TagList tl = new TagList();
|
||||||
tl.addTag("http://foo", "term");
|
tl.addTag("http://foo", "term");
|
||||||
|
|
||||||
Organization org = new Organization();
|
Organization org = new Organization();
|
||||||
ResourceMetadataKeyEnum.TAG_LIST.put(org, tl);
|
ResourceMetadataKeyEnum.TAG_LIST.put(org, tl);
|
||||||
org.setName(methodName);
|
org.setName(methodName);
|
||||||
|
|
||||||
IIdType orgId = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless();
|
IIdType orgId = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
|
@ -1071,7 +1041,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
||||||
|
|
||||||
myPatientDao.deleteByUrl("Patient?organization._tag=http://foo|term", mySrd);
|
myPatientDao.deleteByUrl("Patient?organization._tag=http://foo|term", mySrd);
|
||||||
assertGone(id);
|
assertGone(id);
|
||||||
|
|
||||||
myOrganizationDao.deleteByUrl("Organization?_tag=http://foo|term", mySrd);
|
myOrganizationDao.deleteByUrl("Organization?_tag=http://foo|term", mySrd);
|
||||||
try {
|
try {
|
||||||
myOrganizationDao.read(orgId, mySrd);
|
myOrganizationDao.read(orgId, mySrd);
|
||||||
|
@ -1116,9 +1086,9 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
||||||
/*
|
/*
|
||||||
* Org 2 has a name
|
* Org 2 has a name
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Organization org2 = new Organization();
|
Organization org2 = new Organization();
|
||||||
org2.setName(methodName);
|
org2.setName(methodName);
|
||||||
org2.addIdentifier().setValue(methodName);
|
org2.addIdentifier().setValue(methodName);
|
||||||
IIdType org2Id = myOrganizationDao.create(org2, mySrd).getId().toUnqualifiedVersionless();
|
IIdType org2Id = myOrganizationDao.create(org2, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
|
@ -1131,13 +1101,13 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
||||||
ourLog.info("Org ID 1 : {}", org1Id);
|
ourLog.info("Org ID 1 : {}", org1Id);
|
||||||
ourLog.info("Pat ID 2 : {}", patId2);
|
ourLog.info("Pat ID 2 : {}", patId2);
|
||||||
ourLog.info("Org ID 2 : {}", org2Id);
|
ourLog.info("Org ID 2 : {}", org2Id);
|
||||||
|
|
||||||
myPatientDao.deleteByUrl("Patient?organization.name:missing=true", mySrd);
|
myPatientDao.deleteByUrl("Patient?organization.name:missing=true", mySrd);
|
||||||
assertGone(patId1);
|
assertGone(patId1);
|
||||||
assertNotGone(patId2);
|
assertNotGone(patId2);
|
||||||
assertNotGone(org1Id);
|
assertNotGone(org1Id);
|
||||||
assertNotGone(org2Id);
|
assertNotGone(org2Id);
|
||||||
|
|
||||||
myOrganizationDao.deleteByUrl("Organization?name:missing=true", mySrd);
|
myOrganizationDao.deleteByUrl("Organization?name:missing=true", mySrd);
|
||||||
assertGone(patId1);
|
assertGone(patId1);
|
||||||
assertNotGone(patId2);
|
assertNotGone(patId2);
|
||||||
|
@ -1149,7 +1119,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
||||||
assertGone(patId2);
|
assertGone(patId2);
|
||||||
assertGone(org1Id);
|
assertGone(org1Id);
|
||||||
assertNotGone(org2Id);
|
assertNotGone(org2Id);
|
||||||
|
|
||||||
myOrganizationDao.deleteByUrl("Organization?name:missing=false", mySrd);
|
myOrganizationDao.deleteByUrl("Organization?name:missing=false", mySrd);
|
||||||
assertGone(patId1);
|
assertGone(patId1);
|
||||||
assertGone(patId2);
|
assertGone(patId2);
|
||||||
|
@ -1186,13 +1156,13 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
||||||
String methodName = "testHistoryOverMultiplePages";
|
String methodName = "testHistoryOverMultiplePages";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
for (int i = 0; i < 1000; i++) {
|
* for (int i = 0; i < 1000; i++) {
|
||||||
Patient patient = new Patient();
|
* Patient patient = new Patient();
|
||||||
patient.addName().addFamily(methodName + "__" + i);
|
* patient.addName().addFamily(methodName + "__" + i);
|
||||||
myPatientDao.create(patient).getId().toUnqualifiedVersionless();
|
* myPatientDao.create(patient).getId().toUnqualifiedVersionless();
|
||||||
}
|
* }
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
patient.addName().addFamily(methodName);
|
patient.addName().addFamily(methodName);
|
||||||
IIdType id = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
|
IIdType id = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
@ -2976,4 +2946,27 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidateAgainstDstu2Profile() throws Exception {
|
||||||
|
myDaoConfig.setAllowExternalReferences(true);
|
||||||
|
|
||||||
|
String stream = IOUtils.toString(getClass().getResourceAsStream("/binu_testpatient_structuredefinition_dstu2.xml"), StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
StructureDefinition sd = myFhirCtx.newXmlParser().parseResource(StructureDefinition.class, stream);
|
||||||
|
myStructureDefinitionDao.create(sd, mySrd);
|
||||||
|
|
||||||
|
String rawResource = IOUtils.toString(getClass().getResourceAsStream("/binu_testpatient_resource.json"), StandardCharsets.UTF_8);
|
||||||
|
try {
|
||||||
|
myValueSetDao.validate(null, null, rawResource, EncodingEnum.JSON, ValidationModeEnum.UPDATE, null, mySrd);
|
||||||
|
fail();
|
||||||
|
} catch (PreconditionFailedException e) {
|
||||||
|
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(e.getOperationOutcome()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void afterClassClearContext() {
|
||||||
|
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ import static org.mockito.Mockito.reset;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
@ -82,6 +83,7 @@ import org.hl7.fhir.dstu3.model.UriType;
|
||||||
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.junit.After;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -89,10 +91,7 @@ import org.mockito.ArgumentCaptor;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
|
import ca.uhn.fhir.jpa.dao.*;
|
||||||
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
|
|
||||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
|
|
||||||
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
|
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamString;
|
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamString;
|
||||||
import ca.uhn.fhir.jpa.entity.TagTypeEnum;
|
import ca.uhn.fhir.jpa.entity.TagTypeEnum;
|
||||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||||
|
@ -129,6 +128,12 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
||||||
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoDstu3Test.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoDstu3Test.class);
|
||||||
|
|
||||||
|
@After
|
||||||
|
public final void after() {
|
||||||
|
myDaoConfig.setAllowExternalReferences(new DaoConfig().isAllowExternalReferences());
|
||||||
|
myDaoConfig.setTreatReferencesAsLogical(new DaoConfig().getTreatReferencesAsLogical());
|
||||||
|
}
|
||||||
|
|
||||||
private void assertGone(IIdType theId) {
|
private void assertGone(IIdType theId) {
|
||||||
try {
|
try {
|
||||||
assertNotGone(theId);
|
assertNotGone(theId);
|
||||||
|
@ -152,7 +157,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
||||||
fail("Can't handle type: " + theId.getResourceType());
|
fail("Can't handle type: " + theId.getResourceType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> extractNames(IBundleProvider theSearch) {
|
private List<String> extractNames(IBundleProvider theSearch) {
|
||||||
ArrayList<String> retVal = new ArrayList<String>();
|
ArrayList<String> retVal = new ArrayList<String>();
|
||||||
for (IBaseResource next : theSearch.getResources(0, theSearch.size())) {
|
for (IBaseResource next : theSearch.getResources(0, theSearch.size())) {
|
||||||
|
@ -167,7 +172,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
||||||
retVal.addCoding().setSystem(theSystem).setCode(theCode);
|
retVal.addCoding().setSystem(theSystem).setCode(theCode);
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sort(ArrayList<Coding> thePublished) {
|
private void sort(ArrayList<Coding> thePublished) {
|
||||||
ArrayList<Coding> tags = new ArrayList<Coding>(thePublished);
|
ArrayList<Coding> tags = new ArrayList<Coding>(thePublished);
|
||||||
Collections.sort(tags, new Comparator<Coding>() {
|
Collections.sort(tags, new Comparator<Coding>() {
|
||||||
|
@ -194,7 +199,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<UriType> sortIds(List<UriType> theProfiles) {
|
private List<UriType> sortIds(List<UriType> theProfiles) {
|
||||||
ArrayList<UriType> retVal = new ArrayList<UriType>(theProfiles);
|
ArrayList<UriType> retVal = new ArrayList<UriType>(theProfiles);
|
||||||
Collections.sort(retVal, new Comparator<UriType>() {
|
Collections.sort(retVal, new Comparator<UriType>() {
|
||||||
|
@ -288,21 +293,21 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
||||||
Encounter enc = new Encounter();
|
Encounter enc = new Encounter();
|
||||||
enc.getPeriod().setStartElement(new DateTimeType("2016-05-10")).setEndElement(new DateTimeType("2016-05-20"));
|
enc.getPeriod().setStartElement(new DateTimeType("2016-05-10")).setEndElement(new DateTimeType("2016-05-20"));
|
||||||
String id = myEncounterDao.create(enc, mySrd).getId().toUnqualifiedVersionless().getValue();
|
String id = myEncounterDao.create(enc, mySrd).getId().toUnqualifiedVersionless().getValue();
|
||||||
|
|
||||||
List<String> ids;
|
List<String> ids;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This should not match, per the definition of eq
|
* This should not match, per the definition of eq
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ids = toUnqualifiedVersionlessIdValues(myEncounterDao.search(Encounter.SP_DATE, new DateParam("2016-05-15")));
|
ids = toUnqualifiedVersionlessIdValues(myEncounterDao.search(Encounter.SP_DATE, new DateParam("2016-05-15")));
|
||||||
assertThat(ids, empty());
|
assertThat(ids, empty());
|
||||||
|
|
||||||
ids = toUnqualifiedVersionlessIdValues(myEncounterDao.search(Encounter.SP_DATE, new DateParam("eq2016-05-15")));
|
ids = toUnqualifiedVersionlessIdValues(myEncounterDao.search(Encounter.SP_DATE, new DateParam("eq2016-05-15")));
|
||||||
assertThat(ids, empty());
|
assertThat(ids, empty());
|
||||||
|
|
||||||
// Should match
|
// Should match
|
||||||
|
|
||||||
ids = toUnqualifiedVersionlessIdValues(myEncounterDao.search(Encounter.SP_DATE, new DateParam("eq2016")));
|
ids = toUnqualifiedVersionlessIdValues(myEncounterDao.search(Encounter.SP_DATE, new DateParam("eq2016")));
|
||||||
assertThat(ids, contains(id));
|
assertThat(ids, contains(id));
|
||||||
|
|
||||||
|
@ -468,9 +473,9 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
||||||
CodeSystem cs = new CodeSystem();
|
CodeSystem cs = new CodeSystem();
|
||||||
cs.setStatus(PublicationStatus.DRAFT);
|
cs.setStatus(PublicationStatus.DRAFT);
|
||||||
IIdType id = myCodeSystemDao.create(cs, mySrd).getId().toUnqualifiedVersionless();
|
IIdType id = myCodeSystemDao.create(cs, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
myCodeSystemDao.delete(id, mySrd);
|
myCodeSystemDao.delete(id, mySrd);
|
||||||
|
|
||||||
assertGone(id.toUnqualifiedVersionless());
|
assertGone(id.toUnqualifiedVersionless());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -544,7 +549,6 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateDifferentTypesWithSameForcedId() {
|
public void testCreateDifferentTypesWithSameForcedId() {
|
||||||
String idName = "forcedId";
|
String idName = "forcedId";
|
||||||
|
@ -1047,7 +1051,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDeleteResource() {
|
public void testDeleteResource() {
|
||||||
int initialHistory = myPatientDao.history((Date)null, null, mySrd).size();
|
int initialHistory = myPatientDao.history((Date) null, null, mySrd).size();
|
||||||
|
|
||||||
IIdType id1;
|
IIdType id1;
|
||||||
IIdType id2;
|
IIdType id2;
|
||||||
|
@ -1089,7 +1093,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
||||||
// good
|
// good
|
||||||
}
|
}
|
||||||
|
|
||||||
IBundleProvider history = myPatientDao.history((Date)null, null, mySrd);
|
IBundleProvider history = myPatientDao.history((Date) null, null, mySrd);
|
||||||
assertEquals(4 + initialHistory, history.size());
|
assertEquals(4 + initialHistory, history.size());
|
||||||
List<IBaseResource> resources = history.getResources(0, 4);
|
List<IBaseResource> resources = history.getResources(0, 4);
|
||||||
assertNotNull(ResourceMetadataKeyEnum.DELETED_AT.get((IAnyResource) resources.get(0)));
|
assertNotNull(ResourceMetadataKeyEnum.DELETED_AT.get((IAnyResource) resources.get(0)));
|
||||||
|
@ -1146,7 +1150,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
||||||
Observation obs1 = new Observation();
|
Observation obs1 = new Observation();
|
||||||
obs1.setStatus(ObservationStatus.FINAL);
|
obs1.setStatus(ObservationStatus.FINAL);
|
||||||
IIdType obs1id = myObservationDao.create(obs1).getId().toUnqualifiedVersionless();
|
IIdType obs1id = myObservationDao.create(obs1).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
Observation obs2 = new Observation();
|
Observation obs2 = new Observation();
|
||||||
obs2.setStatus(ObservationStatus.FINAL);
|
obs2.setStatus(ObservationStatus.FINAL);
|
||||||
IIdType obs2id = myObservationDao.create(obs2).getId().toUnqualifiedVersionless();
|
IIdType obs2id = myObservationDao.create(obs2).getId().toUnqualifiedVersionless();
|
||||||
|
@ -1155,19 +1159,19 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
||||||
rpt.addIdentifier().setSystem("foo").setValue("IDENTIFIER");
|
rpt.addIdentifier().setSystem("foo").setValue("IDENTIFIER");
|
||||||
rpt.addResult(new Reference(obs2id));
|
rpt.addResult(new Reference(obs2id));
|
||||||
myDiagnosticReportDao.create(rpt).getId().toUnqualifiedVersionless();
|
myDiagnosticReportDao.create(rpt).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
myObservationDao.read(obs1id);
|
myObservationDao.read(obs1id);
|
||||||
myObservationDao.read(obs2id);
|
myObservationDao.read(obs2id);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
myObservationDao.deleteByUrl("Observation?_has:DiagnosticReport:result:identifier=foo|IDENTIFIER", mySrd);
|
myObservationDao.deleteByUrl("Observation?_has:DiagnosticReport:result:identifier=foo|IDENTIFIER", mySrd);
|
||||||
fail();
|
fail();
|
||||||
} catch (ResourceVersionConflictException e) {
|
} catch (ResourceVersionConflictException e) {
|
||||||
assertConflictException(e);
|
assertConflictException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
myObservationDao.read(obs1id);
|
myObservationDao.read(obs1id);
|
||||||
myObservationDao.read(obs2id);
|
myObservationDao.read(obs2id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -1461,7 +1465,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
// By type
|
// By type
|
||||||
history = myPatientDao.history((Date)null, null, mySrd);
|
history = myPatientDao.history((Date) null, null, mySrd);
|
||||||
assertEquals(fullSize + 1, history.size());
|
assertEquals(fullSize + 1, history.size());
|
||||||
for (int i = 0; i < fullSize; i++) {
|
for (int i = 0; i < fullSize; i++) {
|
||||||
String expected = id.withVersion(Integer.toString(fullSize + 1 - i)).getValue();
|
String expected = id.withVersion(Integer.toString(fullSize + 1 - i)).getValue();
|
||||||
|
@ -1528,7 +1532,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
// By type
|
// By type
|
||||||
history = myPatientDao.history((Date)null, null, mySrd);
|
history = myPatientDao.history((Date) null, null, mySrd);
|
||||||
assertEquals(fullSize + 1, history.size());
|
assertEquals(fullSize + 1, history.size());
|
||||||
for (int i = 0; i < fullSize; i++) {
|
for (int i = 0; i < fullSize; i++) {
|
||||||
String expected = id.withVersion(Integer.toString(fullSize + 1 - i)).getValue();
|
String expected = id.withVersion(Integer.toString(fullSize + 1 - i)).getValue();
|
||||||
|
@ -1585,7 +1589,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
||||||
inPatient.getMeta().addProfile("http://example.com/1");
|
inPatient.getMeta().addProfile("http://example.com/1");
|
||||||
IIdType id = myPatientDao.create(inPatient, mySrd).getId().toUnqualifiedVersionless();
|
IIdType id = myPatientDao.create(inPatient, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
IBundleProvider history = myPatientDao.history((Date)null, null, mySrd);
|
IBundleProvider history = myPatientDao.history((Date) null, null, mySrd);
|
||||||
assertEquals(1, history.size());
|
assertEquals(1, history.size());
|
||||||
Patient outPatient = (Patient) history.getResources(0, 1).get(0);
|
Patient outPatient = (Patient) history.getResources(0, 1).get(0);
|
||||||
assertEquals("version1", inPatient.getName().get(0).getFamily());
|
assertEquals("version1", inPatient.getName().get(0).getFamily());
|
||||||
|
@ -1599,7 +1603,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
||||||
inPatient.getMeta().addProfile("http://example.com/2");
|
inPatient.getMeta().addProfile("http://example.com/2");
|
||||||
myPatientDao.metaAddOperation(id, inPatient.getMeta(), mySrd);
|
myPatientDao.metaAddOperation(id, inPatient.getMeta(), mySrd);
|
||||||
|
|
||||||
history = myPatientDao.history((Date)null, null, mySrd);
|
history = myPatientDao.history((Date) null, null, mySrd);
|
||||||
assertEquals(1, history.size());
|
assertEquals(1, history.size());
|
||||||
outPatient = (Patient) history.getResources(0, 1).get(0);
|
outPatient = (Patient) history.getResources(0, 1).get(0);
|
||||||
assertEquals("version1", inPatient.getName().get(0).getFamily());
|
assertEquals("version1", inPatient.getName().get(0).getFamily());
|
||||||
|
@ -1615,7 +1619,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
||||||
inPatient.getName().get(0).setFamily("version2");
|
inPatient.getName().get(0).setFamily("version2");
|
||||||
myPatientDao.update(inPatient, mySrd);
|
myPatientDao.update(inPatient, mySrd);
|
||||||
|
|
||||||
history = myPatientDao.history((Date)null, null, mySrd);
|
history = myPatientDao.history((Date) null, null, mySrd);
|
||||||
assertEquals(2, history.size());
|
assertEquals(2, history.size());
|
||||||
outPatient = (Patient) history.getResources(0, 2).get(0);
|
outPatient = (Patient) history.getResources(0, 2).get(0);
|
||||||
assertEquals("version2", outPatient.getName().get(0).getFamily());
|
assertEquals("version2", outPatient.getName().get(0).getFamily());
|
||||||
|
@ -1682,13 +1686,13 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> idValues;
|
List<String> idValues;
|
||||||
|
|
||||||
idValues = toUnqualifiedIdValues(myPatientDao.history(id, preDates.get(0), preDates.get(3), mySrd));
|
idValues = toUnqualifiedIdValues(myPatientDao.history(id, preDates.get(0), preDates.get(3), mySrd));
|
||||||
assertThat(idValues, contains(ids.get(2), ids.get(1), ids.get(0)));
|
assertThat(idValues, contains(ids.get(2), ids.get(1), ids.get(0)));
|
||||||
|
|
||||||
idValues = toUnqualifiedIdValues(myPatientDao.history(preDates.get(0), preDates.get(3), mySrd));
|
idValues = toUnqualifiedIdValues(myPatientDao.history(preDates.get(0), preDates.get(3), mySrd));
|
||||||
assertThat(idValues, contains(ids.get(2), ids.get(1), ids.get(0)));
|
assertThat(idValues, contains(ids.get(2), ids.get(1), ids.get(0)));
|
||||||
|
|
||||||
idValues = toUnqualifiedIdValues(mySystemDao.history(preDates.get(0), preDates.get(3), mySrd));
|
idValues = toUnqualifiedIdValues(mySystemDao.history(preDates.get(0), preDates.get(3), mySrd));
|
||||||
assertThat(idValues, contains(ids.get(2), ids.get(1), ids.get(0)));
|
assertThat(idValues, contains(ids.get(2), ids.get(1), ids.get(0)));
|
||||||
}
|
}
|
||||||
|
@ -1709,7 +1713,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
||||||
|
|
||||||
// No since
|
// No since
|
||||||
|
|
||||||
IBundleProvider history = myPatientDao.history((Date)null, null, mySrd);
|
IBundleProvider history = myPatientDao.history((Date) null, null, mySrd);
|
||||||
assertEquals(1, history.size());
|
assertEquals(1, history.size());
|
||||||
Patient outPatient = (Patient) history.getResources(0, 1).get(0);
|
Patient outPatient = (Patient) history.getResources(0, 1).get(0);
|
||||||
assertEquals("version1", inPatient.getName().get(0).getFamily());
|
assertEquals("version1", inPatient.getName().get(0).getFamily());
|
||||||
|
@ -1731,7 +1735,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
||||||
assertEquals(0, history.size());
|
assertEquals(0, history.size());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testHistoryWithInvalidId() throws Exception {
|
public void testHistoryWithInvalidId() throws Exception {
|
||||||
try {
|
try {
|
||||||
|
@ -1815,11 +1819,11 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
||||||
@Test
|
@Test
|
||||||
public void testIndexConditionWithAllOnsetTypes() {
|
public void testIndexConditionWithAllOnsetTypes() {
|
||||||
// DateTimeType.class, Age.class, Period.class, Range.class, StringType.class
|
// DateTimeType.class, Age.class, Period.class, Range.class, StringType.class
|
||||||
|
|
||||||
Condition c0 = new Condition();
|
Condition c0 = new Condition();
|
||||||
c0.setOnset(new DateTimeType("2011-01-01"));
|
c0.setOnset(new DateTimeType("2011-01-01"));
|
||||||
myConditionDao.create(c0, mySrd).getId().toUnqualifiedVersionless();
|
myConditionDao.create(c0, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
Condition c1 = new Condition();
|
Condition c1 = new Condition();
|
||||||
c1.setOnset(new Age().setValue(100L).setCode("AGECODE"));
|
c1.setOnset(new Age().setValue(100L).setCode("AGECODE"));
|
||||||
myConditionDao.create(c1, mySrd).getId().toUnqualifiedVersionless();
|
myConditionDao.create(c1, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
@ -1835,7 +1839,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
||||||
Condition c4 = new Condition();
|
Condition c4 = new Condition();
|
||||||
c4.setOnset(new StringType("FOO"));
|
c4.setOnset(new StringType("FOO"));
|
||||||
myConditionDao.create(c4, mySrd).getId().toUnqualifiedVersionless();
|
myConditionDao.create(c4, mySrd).getId().toUnqualifiedVersionless();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInstanceMetaOperations() {
|
public void testInstanceMetaOperations() {
|
||||||
|
@ -2011,6 +2015,27 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See #534
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testLogicalReferencesAreSearchable() throws IOException {
|
||||||
|
myDaoConfig.setTreatReferencesAsLogical(null);
|
||||||
|
myDaoConfig.addTreatReferencesAsLogical("http://foo.com/identifier*");
|
||||||
|
|
||||||
|
Patient p1 = new Patient();
|
||||||
|
p1.getManagingOrganization().setReference("http://foo.com/identifier/1");
|
||||||
|
String p1id = myPatientDao.create(p1, mySrd).getId().toUnqualifiedVersionless().getValue();
|
||||||
|
|
||||||
|
Patient p2 = new Patient();
|
||||||
|
p2.getManagingOrganization().setReference("http://foo.com/identifier/2");
|
||||||
|
String p2id = myPatientDao.create(p2, mySrd).getId().toUnqualifiedVersionless().getValue();
|
||||||
|
|
||||||
|
IBundleProvider found = myPatientDao.search(Patient.SP_ORGANIZATION, new ReferenceParam("http://foo.com/identifier/1"));
|
||||||
|
assertThat(toUnqualifiedVersionlessIdValues(found), contains(p1id));
|
||||||
|
assertThat(toUnqualifiedVersionlessIdValues(found), not(contains(p2id)));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOrganizationName() {
|
public void testOrganizationName() {
|
||||||
|
|
||||||
|
@ -3297,7 +3322,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
||||||
Date before = new DateTimeType("2011-01-01T10:00:00Z").getValue();
|
Date before = new DateTimeType("2011-01-01T10:00:00Z").getValue();
|
||||||
Date middle = new DateTimeType("2011-01-02T10:00:00Z").getValue();
|
Date middle = new DateTimeType("2011-01-02T10:00:00Z").getValue();
|
||||||
Date after = new DateTimeType("2011-01-03T10:00:00Z").getValue();
|
Date after = new DateTimeType("2011-01-03T10:00:00Z").getValue();
|
||||||
|
|
||||||
CarePlan cp = new CarePlan();
|
CarePlan cp = new CarePlan();
|
||||||
cp.addActivity().getDetail().setScheduled(new Timing().addEvent(before).addEvent(middle).addEvent(after));
|
cp.addActivity().getDetail().setScheduled(new Timing().addEvent(before).addEvent(middle).addEvent(after));
|
||||||
cp.addActivity().getDetail();
|
cp.addActivity().getDetail();
|
||||||
|
@ -3307,9 +3332,9 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
||||||
cp2.addActivity().getDetail().setScheduled(new StringType("FOO"));
|
cp2.addActivity().getDetail().setScheduled(new StringType("FOO"));
|
||||||
cp2.addActivity().getDetail();
|
cp2.addActivity().getDetail();
|
||||||
myCarePlanDao.create(cp2, mySrd).getId().toUnqualifiedVersionless();
|
myCarePlanDao.create(cp2, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
SearchParameterMap params;
|
SearchParameterMap params;
|
||||||
|
|
||||||
params = new SearchParameterMap();
|
params = new SearchParameterMap();
|
||||||
params.add(CarePlan.SP_ACTIVITY_DATE, new DateRangeParam("2010-01-01T10:00:00Z", null));
|
params.add(CarePlan.SP_ACTIVITY_DATE, new DateRangeParam("2010-01-01T10:00:00Z", null));
|
||||||
assertThat(toUnqualifiedVersionlessIdValues(myCarePlanDao.search(params)), contains(id.getValue()));
|
assertThat(toUnqualifiedVersionlessIdValues(myCarePlanDao.search(params)), contains(id.getValue()));
|
||||||
|
@ -3317,7 +3342,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
||||||
params = new SearchParameterMap();
|
params = new SearchParameterMap();
|
||||||
params.add(CarePlan.SP_ACTIVITY_DATE, new DateRangeParam("2011-01-01T10:00:00Z", null));
|
params.add(CarePlan.SP_ACTIVITY_DATE, new DateRangeParam("2011-01-01T10:00:00Z", null));
|
||||||
assertThat(toUnqualifiedVersionlessIdValues(myCarePlanDao.search(params)), contains(id.getValue()));
|
assertThat(toUnqualifiedVersionlessIdValues(myCarePlanDao.search(params)), contains(id.getValue()));
|
||||||
|
|
||||||
params = new SearchParameterMap();
|
params = new SearchParameterMap();
|
||||||
params.add(CarePlan.SP_ACTIVITY_DATE, new DateRangeParam("2012-01-01T10:00:00Z", null));
|
params.add(CarePlan.SP_ACTIVITY_DATE, new DateRangeParam("2012-01-01T10:00:00Z", null));
|
||||||
assertThat(toUnqualifiedVersionlessIdValues(myCarePlanDao.search(params)), empty());
|
assertThat(toUnqualifiedVersionlessIdValues(myCarePlanDao.search(params)), empty());
|
||||||
|
@ -3364,7 +3389,8 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void assertConflictException(ResourceVersionConflictException e) {
|
public static void assertConflictException(ResourceVersionConflictException e) {
|
||||||
assertThat(e.getMessage(), matchesPattern("Unable to delete [a-zA-Z]+/[0-9]+ because at least one resource has a reference to this resource. First reference found was resource [a-zA-Z]+/[0-9]+ in path [a-zA-Z]+.[a-zA-Z]+"));
|
assertThat(e.getMessage(), matchesPattern(
|
||||||
|
"Unable to delete [a-zA-Z]+/[0-9]+ because at least one resource has a reference to this resource. First reference found was resource [a-zA-Z]+/[0-9]+ in path [a-zA-Z]+.[a-zA-Z]+"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<String> toStringList(List<UriType> theUriType) {
|
private static List<String> toStringList(List<UriType> theUriType) {
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
package ca.uhn.fhir.jpa.demo;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.Import;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||||
|
import ca.uhn.fhir.to.FhirTesterMvcConfig;
|
||||||
|
import ca.uhn.fhir.to.TesterConfig;
|
||||||
|
|
||||||
|
//@formatter:off
|
||||||
|
/**
|
||||||
|
* This spring config file configures the web testing module. It serves two
|
||||||
|
* purposes:
|
||||||
|
* 1. It imports FhirTesterMvcConfig, which is the spring config for the
|
||||||
|
* tester itself
|
||||||
|
* 2. It tells the tester which server(s) to talk to, via the testerConfig()
|
||||||
|
* method below
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@Import(FhirTesterMvcConfig.class)
|
||||||
|
public class FhirTesterConfigDstu3 {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This bean tells the testing webpage which servers it should configure itself
|
||||||
|
* to communicate with. In this example we configure it to talk to the local
|
||||||
|
* server, as well as one public server. If you are creating a project to
|
||||||
|
* deploy somewhere else, you might choose to only put your own server's
|
||||||
|
* address here.
|
||||||
|
*
|
||||||
|
* Note the use of the ${serverBase} variable below. This will be replaced with
|
||||||
|
* the base URL as reported by the server itself. Often for a simple Tomcat
|
||||||
|
* (or other container) installation, this will end up being something
|
||||||
|
* like "http://localhost:8080/hapi-fhir-jpaserver-example". If you are
|
||||||
|
* deploying your server to a place with a fully qualified domain name,
|
||||||
|
* you might want to use that instead of using the variable.
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public TesterConfig testerConfig() {
|
||||||
|
TesterConfig retVal = new TesterConfig();
|
||||||
|
retVal
|
||||||
|
.addServer()
|
||||||
|
.withId("home")
|
||||||
|
.withFhirVersion(FhirVersionEnum.DSTU3)
|
||||||
|
.withBaseUrl("${serverBase}/baseDstu3")
|
||||||
|
.withName("Local Tester")
|
||||||
|
.addServer()
|
||||||
|
.withId("hapi")
|
||||||
|
.withFhirVersion(FhirVersionEnum.DSTU3)
|
||||||
|
.withBaseUrl("http://fhirtest.uhn.ca/baseDstu3")
|
||||||
|
.withName("Public HAPI Test Server");
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
//@formatter:on
|
|
@ -46,22 +46,20 @@ public class JpaServerDemo extends RestfulServer {
|
||||||
protected void initialize() throws ServletException {
|
protected void initialize() throws ServletException {
|
||||||
super.initialize();
|
super.initialize();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We want to support FHIR DSTU2 format. This means that the server
|
* We want to support FHIR DSTU2 format. This means that the server
|
||||||
* will use the DSTU2 bundle format and other DSTU2 encoding changes.
|
* will use the DSTU2 bundle format and other DSTU2 encoding changes.
|
||||||
*
|
*
|
||||||
* If you want to use DSTU1 instead, change the following line, and
|
* If you want to use DSTU1 instead, change the following line, and
|
||||||
* change the 2 occurrences of dstu2 in web.xml to dstu1
|
* change the 2 occurrences of dstu2 in web.xml to dstu1
|
||||||
*/
|
*/
|
||||||
FhirVersionEnum fhirVersion = FhirVersionEnum.DSTU2;
|
FhirVersionEnum fhirVersion = FhirVersionEnum.DSTU3;
|
||||||
FhirContext context = new FhirContext(fhirVersion);
|
setFhirContext(new FhirContext(fhirVersion));
|
||||||
|
|
||||||
setFhirContext(context);
|
|
||||||
|
|
||||||
// Get the spring context from the web container (it's declared in web.xml)
|
// Get the spring context from the web container (it's declared in web.xml)
|
||||||
myAppCtx = ContextLoaderListener.getCurrentWebApplicationContext();
|
myAppCtx = ContextLoaderListener.getCurrentWebApplicationContext();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The BaseJavaConfigDstu2.java class is a spring configuration
|
* The BaseJavaConfigDstu2.java class is a spring configuration
|
||||||
* file which is automatically generated as a part of hapi-fhir-jpaserver-base and
|
* file which is automatically generated as a part of hapi-fhir-jpaserver-base and
|
||||||
* contains bean definitions for a resource provider for each resource type
|
* contains bean definitions for a resource provider for each resource type
|
||||||
|
@ -78,8 +76,8 @@ public class JpaServerDemo extends RestfulServer {
|
||||||
}
|
}
|
||||||
List<IResourceProvider> beans = myAppCtx.getBean(resourceProviderBeanName, List.class);
|
List<IResourceProvider> beans = myAppCtx.getBean(resourceProviderBeanName, List.class);
|
||||||
setResourceProviders(beans);
|
setResourceProviders(beans);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The system provider implements non-resource-type methods, such as
|
* The system provider implements non-resource-type methods, such as
|
||||||
* transaction, and global history.
|
* transaction, and global history.
|
||||||
*/
|
*/
|
||||||
|
@ -174,15 +172,15 @@ public class JpaServerDemo extends RestfulServer {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If you are hosting this server at a specific DNS name, the server will try to
|
* If you are hosting this server at a specific DNS name, the server will try to
|
||||||
* figure out the FHIR base URL based on what the web container tells it, but
|
* figure out the FHIR base URL based on what the web container tells it, but
|
||||||
* this doesn't always work. If you are setting links in your search bundles that
|
* this doesn't always work. If you are setting links in your search bundles that
|
||||||
* just refer to "localhost", you might want to use a server address strategy:
|
* just refer to "localhost", you might want to use a server address strategy:
|
||||||
*/
|
*/
|
||||||
//setServerAddressStrategy(new HardcodedServerAddressStrategy("http://mydomain.com/fhir/baseDstu2"));
|
//setServerAddressStrategy(new HardcodedServerAddressStrategy("http://mydomain.com/fhir/baseDstu2"));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If you are using DSTU3+, you may want to add a terminology uploader, which allows
|
* If you are using DSTU3+, you may want to add a terminology uploader, which allows
|
||||||
* uploading of external terminologies such as Snomed CT. Note that this uploader
|
* uploading of external terminologies such as Snomed CT. Note that this uploader
|
||||||
* does not have any security attached (any anonymous user may use it by default)
|
* does not have any security attached (any anonymous user may use it by default)
|
||||||
* so it is a potential security vulnerability. Consider using an AuthorizationInterceptor
|
* so it is a potential security vulnerability. Consider using an AuthorizationInterceptor
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
<context-param>
|
<context-param>
|
||||||
<param-name>contextConfigLocation</param-name>
|
<param-name>contextConfigLocation</param-name>
|
||||||
<param-value>
|
<param-value>
|
||||||
ca.uhn.fhir.jpa.demo.FhirServerConfig
|
ca.uhn.fhir.jpa.demo.FhirServerConfigDstu3
|
||||||
</param-value>
|
</param-value>
|
||||||
</context-param>
|
</context-param>
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@
|
||||||
</init-param>
|
</init-param>
|
||||||
<init-param>
|
<init-param>
|
||||||
<param-name>contextConfigLocation</param-name>
|
<param-name>contextConfigLocation</param-name>
|
||||||
<param-value>ca.uhn.fhir.jpa.demo.FhirTesterConfig</param-value>
|
<param-value>ca.uhn.fhir.jpa.demo.FhirTesterConfigDstu3</param-value>
|
||||||
</init-param>
|
</init-param>
|
||||||
<load-on-startup>2</load-on-startup>
|
<load-on-startup>2</load-on-startup>
|
||||||
</servlet>
|
</servlet>
|
||||||
|
@ -42,14 +42,14 @@
|
||||||
</init-param>
|
</init-param>
|
||||||
<init-param>
|
<init-param>
|
||||||
<param-name>FhirVersion</param-name>
|
<param-name>FhirVersion</param-name>
|
||||||
<param-value>DSTU2</param-value>
|
<param-value>DSTU3</param-value>
|
||||||
</init-param>
|
</init-param>
|
||||||
<load-on-startup>1</load-on-startup>
|
<load-on-startup>1</load-on-startup>
|
||||||
</servlet>
|
</servlet>
|
||||||
|
|
||||||
<servlet-mapping>
|
<servlet-mapping>
|
||||||
<servlet-name>fhirServlet</servlet-name>
|
<servlet-name>fhirServlet</servlet-name>
|
||||||
<url-pattern>/baseDstu2/*</url-pattern>
|
<url-pattern>/baseDstu3/*</url-pattern>
|
||||||
</servlet-mapping>
|
</servlet-mapping>
|
||||||
|
|
||||||
<servlet-mapping>
|
<servlet-mapping>
|
||||||
|
|
|
@ -7,13 +7,13 @@ import java.io.IOException;
|
||||||
|
|
||||||
import org.eclipse.jetty.server.Server;
|
import org.eclipse.jetty.server.Server;
|
||||||
import org.eclipse.jetty.webapp.WebAppContext;
|
import org.eclipse.jetty.webapp.WebAppContext;
|
||||||
|
import org.hl7.fhir.dstu3.model.Patient;
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
|
||||||
import ca.uhn.fhir.rest.client.IGenericClient;
|
import ca.uhn.fhir.rest.client.IGenericClient;
|
||||||
import ca.uhn.fhir.rest.client.ServerValidationModeEnum;
|
import ca.uhn.fhir.rest.client.ServerValidationModeEnum;
|
||||||
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
|
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
|
||||||
|
@ -21,7 +21,7 @@ import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
|
||||||
public class ExampleServerIT {
|
public class ExampleServerIT {
|
||||||
|
|
||||||
private static IGenericClient ourClient;
|
private static IGenericClient ourClient;
|
||||||
private static FhirContext ourCtx = FhirContext.forDstu2();
|
private static FhirContext ourCtx = FhirContext.forDstu3();
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ExampleServerIT.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ExampleServerIT.class);
|
||||||
|
|
||||||
private static int ourPort;
|
private static int ourPort;
|
||||||
|
@ -34,11 +34,11 @@ public class ExampleServerIT {
|
||||||
String methodName = "testCreateResourceConditional";
|
String methodName = "testCreateResourceConditional";
|
||||||
|
|
||||||
Patient pt = new Patient();
|
Patient pt = new Patient();
|
||||||
pt.addName().addFamily(methodName);
|
pt.addName().setFamily(methodName);
|
||||||
IIdType id = ourClient.create().resource(pt).execute().getId();
|
IIdType id = ourClient.create().resource(pt).execute().getId();
|
||||||
|
|
||||||
Patient pt2 = ourClient.read().resource(Patient.class).withId(id).execute();
|
Patient pt2 = ourClient.read().resource(Patient.class).withId(id).execute();
|
||||||
assertEquals(methodName, pt2.getName().get(0).getFamily().get(0).getValue());
|
assertEquals(methodName, pt2.getName().get(0).getFamily());
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterClass
|
@AfterClass
|
||||||
|
@ -72,7 +72,7 @@ public class ExampleServerIT {
|
||||||
|
|
||||||
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
|
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
|
||||||
ourCtx.getRestfulClientFactory().setSocketTimeout(1200 * 1000);
|
ourCtx.getRestfulClientFactory().setSocketTimeout(1200 * 1000);
|
||||||
ourServerBase = "http://localhost:" + ourPort + "/baseDstu2";
|
ourServerBase = "http://localhost:" + ourPort + "/baseDstu3";
|
||||||
ourClient = ourCtx.newRestfulGenericClient(ourServerBase);
|
ourClient = ourCtx.newRestfulGenericClient(ourServerBase);
|
||||||
ourClient.registerInterceptor(new LoggingInterceptor(true));
|
ourClient.registerInterceptor(new LoggingInterceptor(true));
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
package ca.uhn.fhirtest.config;
|
package ca.uhn.fhirtest.config;
|
||||||
|
|
||||||
import java.util.Properties;
|
import ca.uhn.fhir.jpa.config.BaseJavaConfigDstu2;
|
||||||
|
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
||||||
import javax.persistence.EntityManagerFactory;
|
import ca.uhn.fhir.jpa.util.SubscriptionsRequireManualActivationInterceptorDstu2;
|
||||||
import javax.sql.DataSource;
|
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||||
|
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
||||||
|
import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor;
|
||||||
|
import ca.uhn.fhir.rest.server.interceptor.ResponseValidatingInterceptor;
|
||||||
|
import ca.uhn.fhir.validation.ResultSeverityEnum;
|
||||||
|
import ca.uhn.fhirtest.interceptor.TdlSecurityInterceptor;
|
||||||
import org.apache.commons.dbcp2.BasicDataSource;
|
import org.apache.commons.dbcp2.BasicDataSource;
|
||||||
import org.apache.commons.lang3.time.DateUtils;
|
import org.apache.commons.lang3.time.DateUtils;
|
||||||
import org.hibernate.dialect.DerbyTenSevenDialect;
|
import org.hibernate.dialect.DerbyTenSevenDialect;
|
||||||
|
@ -13,18 +17,16 @@ import org.springframework.beans.factory.annotation.Autowire;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
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.DependsOn;
|
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
|
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
|
||||||
import org.springframework.orm.jpa.JpaTransactionManager;
|
import org.springframework.orm.jpa.JpaTransactionManager;
|
||||||
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||||
|
|
||||||
import ca.uhn.fhir.jpa.config.BaseJavaConfigDstu2;
|
import javax.persistence.EntityManagerFactory;
|
||||||
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
import javax.sql.DataSource;
|
||||||
import ca.uhn.fhir.jpa.util.SubscriptionsRequireManualActivationInterceptorDstu2;
|
import java.util.Properties;
|
||||||
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
|
||||||
import ca.uhn.fhirtest.interceptor.TdlSecurityInterceptor;
|
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@Import(CommonConfig.class)
|
@Import(CommonConfig.class)
|
||||||
|
@ -113,6 +115,49 @@ public class TdlDstu2Config extends BaseJavaConfigDstu2 {
|
||||||
return extraProperties;
|
return extraProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bean which validates incoming requests
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
@Lazy
|
||||||
|
public RequestValidatingInterceptor requestValidatingInterceptor() {
|
||||||
|
RequestValidatingInterceptor requestValidator = new RequestValidatingInterceptor();
|
||||||
|
requestValidator.setFailOnSeverity(null);
|
||||||
|
requestValidator.setAddResponseHeaderOnSeverity(null);
|
||||||
|
requestValidator.setAddResponseOutcomeHeaderOnSeverity(ResultSeverityEnum.INFORMATION);
|
||||||
|
requestValidator.addValidatorModule(instanceValidatorDstu2());
|
||||||
|
requestValidator.setIgnoreValidatorExceptions(true);
|
||||||
|
|
||||||
|
return requestValidator;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bean which validates outgoing responses
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
@Lazy
|
||||||
|
public ResponseValidatingInterceptor responseValidatingInterceptor() {
|
||||||
|
ResponseValidatingInterceptor responseValidator = new ResponseValidatingInterceptor();
|
||||||
|
responseValidator.setResponseHeaderValueNoIssues("Validation did not detect any issues");
|
||||||
|
responseValidator.setFailOnSeverity(null);
|
||||||
|
responseValidator.setAddResponseHeaderOnSeverity(null);
|
||||||
|
responseValidator.setAddResponseOutcomeHeaderOnSeverity(ResultSeverityEnum.INFORMATION);
|
||||||
|
responseValidator.addExcludeOperationType(RestOperationTypeEnum.METADATA);
|
||||||
|
responseValidator.addExcludeOperationType(RestOperationTypeEnum.EXTENDED_OPERATION_INSTANCE);
|
||||||
|
responseValidator.addExcludeOperationType(RestOperationTypeEnum.EXTENDED_OPERATION_SERVER);
|
||||||
|
responseValidator.addExcludeOperationType(RestOperationTypeEnum.EXTENDED_OPERATION_TYPE);
|
||||||
|
responseValidator.addExcludeOperationType(RestOperationTypeEnum.GET_PAGE);
|
||||||
|
responseValidator.addExcludeOperationType(RestOperationTypeEnum.HISTORY_INSTANCE);
|
||||||
|
responseValidator.addExcludeOperationType(RestOperationTypeEnum.HISTORY_SYSTEM);
|
||||||
|
responseValidator.addExcludeOperationType(RestOperationTypeEnum.HISTORY_TYPE);
|
||||||
|
responseValidator.addExcludeOperationType(RestOperationTypeEnum.SEARCH_SYSTEM);
|
||||||
|
responseValidator.addExcludeOperationType(RestOperationTypeEnum.SEARCH_TYPE);
|
||||||
|
responseValidator.addValidatorModule(instanceValidatorDstu2());
|
||||||
|
responseValidator.setIgnoreValidatorExceptions(true);
|
||||||
|
|
||||||
|
return responseValidator;
|
||||||
|
}
|
||||||
|
|
||||||
@Bean(autowire=Autowire.BY_TYPE)
|
@Bean(autowire=Autowire.BY_TYPE)
|
||||||
public IServerInterceptor subscriptionSecurityInterceptor() {
|
public IServerInterceptor subscriptionSecurityInterceptor() {
|
||||||
return new SubscriptionsRequireManualActivationInterceptorDstu2();
|
return new SubscriptionsRequireManualActivationInterceptorDstu2();
|
||||||
|
|
|
@ -1,30 +1,28 @@
|
||||||
package ca.uhn.fhirtest.config;
|
package ca.uhn.fhirtest.config;
|
||||||
|
|
||||||
import java.util.Properties;
|
import ca.uhn.fhir.jpa.config.BaseJavaConfigDstu2;
|
||||||
|
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
||||||
import javax.persistence.EntityManagerFactory;
|
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
||||||
import javax.sql.DataSource;
|
import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor;
|
||||||
|
import ca.uhn.fhir.validation.ResultSeverityEnum;
|
||||||
|
import ca.uhn.fhirtest.interceptor.PublicSecurityInterceptor;
|
||||||
import org.apache.commons.dbcp2.BasicDataSource;
|
import org.apache.commons.dbcp2.BasicDataSource;
|
||||||
import org.apache.commons.lang3.time.DateUtils;
|
import org.apache.commons.lang3.time.DateUtils;
|
||||||
import org.hibernate.dialect.PostgreSQL94Dialect;
|
import org.hibernate.dialect.PostgreSQL94Dialect;
|
||||||
import org.hibernate.jpa.HibernatePersistenceProvider;
|
import org.hibernate.jpa.HibernatePersistenceProvider;
|
||||||
import org.springframework.beans.factory.annotation.Autowire;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
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.DependsOn;
|
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
|
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
|
||||||
import org.springframework.orm.jpa.JpaTransactionManager;
|
import org.springframework.orm.jpa.JpaTransactionManager;
|
||||||
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||||
|
|
||||||
import ca.uhn.fhir.jpa.config.BaseJavaConfigDstu2;
|
import javax.persistence.EntityManagerFactory;
|
||||||
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
import javax.sql.DataSource;
|
||||||
import ca.uhn.fhir.jpa.util.SubscriptionsRequireManualActivationInterceptorDstu2;
|
import java.util.Properties;
|
||||||
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
|
||||||
import ca.uhn.fhirtest.interceptor.PublicSecurityInterceptor;
|
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@Import(CommonConfig.class)
|
@Import(CommonConfig.class)
|
||||||
|
@ -114,6 +112,22 @@ public class TestDstu2Config extends BaseJavaConfigDstu2 {
|
||||||
return extraProperties;
|
return extraProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bean which validates incoming requests
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
@Lazy
|
||||||
|
public RequestValidatingInterceptor requestValidatingInterceptor() {
|
||||||
|
RequestValidatingInterceptor requestValidator = new RequestValidatingInterceptor();
|
||||||
|
requestValidator.setFailOnSeverity(null);
|
||||||
|
requestValidator.setAddResponseHeaderOnSeverity(null);
|
||||||
|
requestValidator.setAddResponseOutcomeHeaderOnSeverity(ResultSeverityEnum.INFORMATION);
|
||||||
|
requestValidator.addValidatorModule(instanceValidatorDstu2());
|
||||||
|
requestValidator.setIgnoreValidatorExceptions(true);
|
||||||
|
|
||||||
|
return requestValidator;
|
||||||
|
}
|
||||||
|
|
||||||
// @Bean(autowire = Autowire.BY_TYPE)
|
// @Bean(autowire = Autowire.BY_TYPE)
|
||||||
// public IServerInterceptor subscriptionSecurityInterceptor() {
|
// public IServerInterceptor subscriptionSecurityInterceptor() {
|
||||||
// return new SubscriptionsRequireManualActivationInterceptorDstu2();
|
// return new SubscriptionsRequireManualActivationInterceptorDstu2();
|
||||||
|
|
|
@ -26,6 +26,27 @@
|
||||||
Web testing UI displayed an error when a transaction was pasted into the UI
|
Web testing UI displayed an error when a transaction was pasted into the UI
|
||||||
for a DSTU2 server. Thanks to Suresh Kumar for reporting!
|
for a DSTU2 server. Thanks to Suresh Kumar for reporting!
|
||||||
</action>
|
</action>
|
||||||
|
<action type="add">
|
||||||
|
DaoConfig#setAllowInlineMatchUrlReferences() now defaults to
|
||||||
|
<![CDATA[<code>true</code>]]> since inline conditional references
|
||||||
|
are now a part of the FHIR specification. Thanks to Jan Dědek for
|
||||||
|
pointing this out!
|
||||||
|
</action>
|
||||||
|
<action type="add" issue="609">
|
||||||
|
hapi-fhir-jpaserver-base now exposes a
|
||||||
|
<![CDATA[<code>FhirInstanceValidator</code> bean named <code>"myInstanceValidatorDstu2"</code>]]>
|
||||||
|
for DSTU2. A similar bean for DSTU3 was previously implemented.
|
||||||
|
</action>
|
||||||
|
<action type="add" issue="453">
|
||||||
|
hapi-fhir-jpaserver-example project now defaults to STU3 mode instead of
|
||||||
|
the previous DSTU2. Thanks to Joel Schneider for the pull request!
|
||||||
|
</action>
|
||||||
|
<action type="add" issue="534">
|
||||||
|
JPA server now has a setting on the DaoConfig to force it to treat
|
||||||
|
certain reference URLs or reference URL patterns as logical URLs instead
|
||||||
|
of literal ones, meaning that the server will not try to resolve these
|
||||||
|
URLs. Thanks to Eeva Turkka for the suggestion!
|
||||||
|
</action>
|
||||||
</release>
|
</release>
|
||||||
<release version="2.3" date="2017-03-18">
|
<release version="2.3" date="2017-03-18">
|
||||||
<action type="add">
|
<action type="add">
|
||||||
|
|
|
@ -174,6 +174,38 @@ public DaoConfig daoConfig() {
|
||||||
return retVal;
|
return retVal;
|
||||||
}]]></source>
|
}]]></source>
|
||||||
</subsection>
|
</subsection>
|
||||||
|
|
||||||
|
<subsection name="Logical References">
|
||||||
|
|
||||||
|
<p>
|
||||||
|
In some cases, you may have references which are <i>Logical References</i>,
|
||||||
|
which means that they act as an identifier and not necessarily as a literal
|
||||||
|
web address.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
A common use for logical references is in references to conformance
|
||||||
|
resources, such as ValueSets, StructureDefinitions, etc. For example,
|
||||||
|
you might refer to the ValueSet
|
||||||
|
<code>http://hl7.org/fhir/ValueSet/quantity-comparator</code>
|
||||||
|
from your own resources. In this case, you are not neccesarily telling
|
||||||
|
the server that this is a real address that it should resolve, but
|
||||||
|
rather that this is an identifier for a ValueSet where
|
||||||
|
<code>ValueSet.url</code> has the given URI/URL.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
HAPI can be configured to treat certain URI/URL patterns as
|
||||||
|
logical by using the DaoConfig#setTreatReferencesAsLogical property
|
||||||
|
(see <a href="./apidocs-jpaserver/ca/uhn/fhir/jpa/dao/DaoConfig.html#setTreatReferencesAsLogical-java.util.Set-">JavaDoc</a>).
|
||||||
|
For example:
|
||||||
|
</p>
|
||||||
|
<code>
|
||||||
|
// Treat specific URL as logical
|
||||||
|
myDaoConfig.getTreatReferencesAsLogical().add("http://mysystem.com/ValueSet/cats-and-dogs");
|
||||||
|
|
||||||
|
// Treat all references with given prefix as logical
|
||||||
|
myDaoConfig.getTreatReferencesAsLogical().add("http://mysystem.com/mysystem-vs-*");
|
||||||
|
</code>
|
||||||
|
</subsection>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue