JPA Cleanup (#4278)

* JPA cleanup

* Test fixes

* Cleanup

* Resolve fixme

* Fix bad changelog entry

* A bit of documentation reworking

* Version bump

* POM bump

* Avoid timeout

* Build fix

* HTMLUnit bump
This commit is contained in:
James Agnew 2022-11-24 14:32:56 -05:00 committed by GitHub
parent 028c3ed5c1
commit c3697a5f87
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
129 changed files with 454 additions and 2340 deletions

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId> <artifactId>hapi-fhir</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -29,6 +29,7 @@ import ca.uhn.fhir.model.valueset.BundleEntryTransactionMethodEnum;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
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.IPrimitiveType; import org.hl7.fhir.instance.model.api.IPrimitiveType;
import java.io.Serializable; import java.io.Serializable;
@ -64,6 +65,23 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
*/ */
public abstract class ResourceMetadataKeyEnum<T> implements Serializable { public abstract class ResourceMetadataKeyEnum<T> implements Serializable {
// TODO: JA - Replace all of the various other get/put methods in subclasses with just using the two that are here
public T get(IBaseResource theResource) {
if (theResource instanceof IAnyResource) {
return (T) theResource.getUserData(name());
} else {
return (T) ((IResource)theResource).getResourceMetadata().get(this);
}
}
public void put(IBaseResource theResource, T theValue) {
if (theResource instanceof IAnyResource) {
theResource.setUserData(name(), theValue);
} else {
((IResource)theResource).getResourceMetadata().put(this, theValue);
}
}
/** /**
* If present and populated with a date/time (as an instance of {@link InstantDt}), this value is an indication that the resource is in the deleted state. This key is only used in a limited number * If present and populated with a date/time (as an instance of {@link InstantDt}), this value is an indication that the resource is in the deleted state. This key is only used in a limited number
* of scenarios, such as POSTing transaction bundles to a server, or returning resource history. * of scenarios, such as POSTing transaction bundles to a server, or returning resource history.
@ -71,29 +89,19 @@ public abstract class ResourceMetadataKeyEnum<T> implements Serializable {
* Values for this key are of type <b>{@link InstantDt}</b> * Values for this key are of type <b>{@link InstantDt}</b>
* </p> * </p>
*/ */
public static final ResourceMetadataKeySupportingAnyResource<InstantDt, IPrimitiveType<Date>> DELETED_AT = new ResourceMetadataKeySupportingAnyResource<InstantDt, IPrimitiveType<Date>>("DELETED_AT") { public static final ResourceMetadataKeyEnum<IPrimitiveType<Date>> DELETED_AT = new ResourceMetadataKeyEnum<>("DELETED_AT") {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Override @Override
public InstantDt get(IResource theResource) { public IPrimitiveType<Date> get(IResource theResource) {
return getInstantFromMetadataOrNullIfNone(theResource.getResourceMetadata(), DELETED_AT); return (IPrimitiveType<Date>) theResource.getResourceMetadata().get(this);
}
@SuppressWarnings("unchecked")
@Override
public IPrimitiveType<Date> get(IAnyResource theResource) {
return (IPrimitiveType<Date>) theResource.getUserData(DELETED_AT.name());
} }
@Override @Override
public void put(IResource theResource, InstantDt theObject) { public void put(IResource theResource, IPrimitiveType<Date> theObject) {
theResource.getResourceMetadata().put(DELETED_AT, theObject); theResource.getResourceMetadata().put(this, theObject);
} }
@Override
public void put(IAnyResource theResource, IPrimitiveType<Date> theObject) {
theResource.setUserData(DELETED_AT.name(), theObject);
}
}; };
/** /**

View File

@ -34,6 +34,9 @@ import org.slf4j.LoggerFactory;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.util.function.Function; import java.util.function.Function;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
@ -86,6 +89,10 @@ public class ClasspathUtil {
return retVal; return retVal;
} }
public static Reader loadResourceAsReader(String theClasspath) {
return new InputStreamReader(loadResourceAsStream(theClasspath), StandardCharsets.UTF_8);
}
/** /**
* Load a classpath resource, throw an {@link InternalErrorException} if not found * Load a classpath resource, throw an {@link InternalErrorException} if not found
*/ */

View File

@ -107,6 +107,7 @@ public enum VersionEnum {
V6_1_4, V6_1_4,
V6_2_0, V6_2_0,
V6_2_1, V6_2_1,
// Dev Build
V6_3_0 V6_3_0
; ;

View File

@ -130,7 +130,7 @@ ca.uhn.fhir.jpa.search.builder.predicate.TokenPredicateBuilder.invalidCodeMissin
ca.uhn.fhir.jpa.term.TermConceptMappingSvcImpl.matchesFound=Matches found ca.uhn.fhir.jpa.term.TermConceptMappingSvcImpl.matchesFound=Matches found
ca.uhn.fhir.jpa.term.TermConceptMappingSvcImpl.noMatchesFound=No Matches found ca.uhn.fhir.jpa.term.TermConceptMappingSvcImpl.noMatchesFound=No Matches found
ca.uhn.fhir.jpa.dao.r4.FhirResourceDaoSearchParameterR4.invalidSearchParamExpression=The expression "{0}" can not be evaluated and may be invalid: {1} ca.uhn.fhir.jpa.dao.JpaResourceDaoSearchParameter.invalidSearchParamExpression=The expression "{0}" can not be evaluated and may be invalid: {1}
ca.uhn.fhir.jpa.search.builder.QueryStack.textModifierDisabledForSearchParam=The :text modifier is disabled for this search parameter ca.uhn.fhir.jpa.search.builder.QueryStack.textModifierDisabledForSearchParam=The :text modifier is disabled for this search parameter
ca.uhn.fhir.jpa.search.builder.QueryStack.textModifierDisabledForServer=The :text modifier is disabled on this server ca.uhn.fhir.jpa.search.builder.QueryStack.textModifierDisabledForServer=The :text modifier is disabled on this server

View File

@ -32,6 +32,15 @@ public class ClasspathUtilTest {
} }
} }
@Test
public void testLoadResourceAsReaderNotFound() {
try {
ClasspathUtil.loadResourceAsReader("/FOOOOOO");
} catch (InternalErrorException e) {
assertEquals(Msg.code(1758) + "Unable to find classpath resource: /FOOOOOO", e.getMessage());
}
}
/** /**
* Should not throw any exception * Should not throw any exception
*/ */

View File

@ -8,6 +8,7 @@ import java.util.stream.Collectors;
import static org.hamcrest.CoreMatchers.hasItem; import static org.hamcrest.CoreMatchers.hasItem;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class VersionEnumTest { public class VersionEnumTest {
@ -18,10 +19,25 @@ public class VersionEnumTest {
.collect(Collectors.toList()); .collect(Collectors.toList());
String version = VersionUtil.getVersion(); String version = VersionUtil.getVersion();
version = "V" + version.replace(".", "_");
version = version.replaceAll("-PRE[0-9]+", ""); version = version.replaceAll("-PRE[0-9]+", "");
version = version.replace("-SNAPSHOT", ""); version = version.replace("-SNAPSHOT", "");
String[] parts = version.split("\\.");
assertEquals(3, parts.length);
int major = Integer.parseInt(parts[0]);
int minor = Integer.parseInt(parts[1]);
int patch = Integer.parseInt(parts[2]);
if (major >= 6 && minor >= 3) {
if (minor % 2 == 1) {
patch = 0;
}
}
version = major + "." + minor + "." + patch;
version = "V" + version.replace(".", "_");
assertThat(versions, hasItem(version)); assertThat(versions, hasItem(version));
} }

View File

@ -3,14 +3,14 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-bom</artifactId> <artifactId>hapi-fhir-bom</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<name>HAPI FHIR BOM</name> <name>HAPI FHIR BOM</name>
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId> <artifactId>hapi-fhir</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-cli</artifactId> <artifactId>hapi-fhir-cli</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../../hapi-deployable-pom</relativePath> <relativePath>../../hapi-deployable-pom</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId> <artifactId>hapi-fhir</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -47,9 +47,12 @@ import org.hl7.fhir.r4.model.Coding;
import org.hl7.fhir.r4.model.ConceptMap; import org.hl7.fhir.r4.model.ConceptMap;
import org.hl7.fhir.r4.model.ValueSet; import org.hl7.fhir.r4.model.ValueSet;
import org.hl7.fhir.r5.model.CapabilityStatement; import org.hl7.fhir.r5.model.CapabilityStatement;
import org.hl7.fhir.r5.model.SearchParameter;
import java.util.List; import java.util.List;
import static org.apache.commons.lang3.StringUtils.isBlank;
/** /**
* This class converts versions of various resources to/from a canonical version * This class converts versions of various resources to/from a canonical version
* of the resource. The specific version that is considered canonical is arbitrary * of the resource. The specific version that is considered canonical is arbitrary
@ -68,14 +71,13 @@ public class VersionCanonicalizer {
private static final BaseAdvisor_10_50 ADVISOR_10_50 = new BaseAdvisor_10_50(false); private static final BaseAdvisor_10_50 ADVISOR_10_50 = new BaseAdvisor_10_50(false);
private static final BaseAdvisor_40_50 ADVISOR_40_50 = new BaseAdvisor_40_50(false); private static final BaseAdvisor_40_50 ADVISOR_40_50 = new BaseAdvisor_40_50(false);
private static final BaseAdvisor_43_50 ADVISOR_43_50 = new BaseAdvisor_43_50(false); private static final BaseAdvisor_43_50 ADVISOR_43_50 = new BaseAdvisor_43_50(false);
@SuppressWarnings("rawtypes")
private final IStrategy myStrategy; private final IStrategy myStrategy;
public VersionCanonicalizer(FhirContext theTargetContext) { public VersionCanonicalizer(FhirContext theTargetContext) {
this(theTargetContext.getVersion().getVersion()); this(theTargetContext.getVersion().getVersion());
} }
@SuppressWarnings("EnumSwitchStatementWhichMissesCases") @SuppressWarnings({"EnumSwitchStatementWhichMissesCases", "EnhancedSwitchMigration"})
public VersionCanonicalizer(FhirVersionEnum theTargetVersion) { public VersionCanonicalizer(FhirVersionEnum theTargetVersion) {
switch (theTargetVersion) { switch (theTargetVersion) {
case DSTU2: case DSTU2:
@ -160,9 +162,13 @@ public class VersionCanonicalizer {
return myStrategy.conceptMapToCanonical(theConceptMap); return myStrategy.conceptMapToCanonical(theConceptMap);
} }
private interface IStrategy<T extends IBaseResource> { public <T extends IBaseResource> SearchParameter searchParameterToCanonical(T theSearchParameter) {
return myStrategy.searchParameterToCanonical(theSearchParameter);
}
CapabilityStatement capabilityStatementToCanonical(T theCapabilityStatement); private interface IStrategy {
CapabilityStatement capabilityStatementToCanonical(IBaseResource theCapabilityStatement);
Coding codingToCanonical(IBaseCoding theCoding); Coding codingToCanonical(IBaseCoding theCoding);
@ -175,9 +181,11 @@ public class VersionCanonicalizer {
IBaseResource valueSetFromCanonical(ValueSet theValueSet); IBaseResource valueSetFromCanonical(ValueSet theValueSet);
ConceptMap conceptMapToCanonical(IBaseResource theConceptMap); ConceptMap conceptMapToCanonical(IBaseResource theConceptMap);
SearchParameter searchParameterToCanonical(IBaseResource theSearchParameter);
} }
private class Dstu2Strategy implements IStrategy<ca.uhn.fhir.model.dstu2.resource.BaseResource> { private static class Dstu2Strategy implements IStrategy {
private final FhirContext myDstu2Hl7OrgContext = FhirContext.forDstu2Hl7OrgCached(); private final FhirContext myDstu2Hl7OrgContext = FhirContext.forDstu2Hl7OrgCached();
@ -189,7 +197,7 @@ public class VersionCanonicalizer {
} }
@Override @Override
public CapabilityStatement capabilityStatementToCanonical(ca.uhn.fhir.model.dstu2.resource.BaseResource theCapabilityStatement) { public CapabilityStatement capabilityStatementToCanonical(IBaseResource theCapabilityStatement) {
org.hl7.fhir.dstu2.model.Resource reencoded = reencodeToHl7Org(theCapabilityStatement); org.hl7.fhir.dstu2.model.Resource reencoded = reencodeToHl7Org(theCapabilityStatement);
return (CapabilityStatement) VersionConvertorFactory_10_50.convertResource(reencoded, ADVISOR_10_50); return (CapabilityStatement) VersionConvertorFactory_10_50.convertResource(reencoded, ADVISOR_10_50);
} }
@ -224,8 +232,7 @@ public class VersionCanonicalizer {
@Override @Override
public ValueSet valueSetToCanonical(IBaseResource theValueSet) { public ValueSet valueSetToCanonical(IBaseResource theValueSet) {
org.hl7.fhir.dstu2.model.Resource reencoded = reencodeToHl7Org(theValueSet); org.hl7.fhir.dstu2.model.Resource reencoded = reencodeToHl7Org(theValueSet);
ValueSet valueSet = (ValueSet) VersionConvertorFactory_10_40.convertResource(reencoded, ADVISOR_10_40); return (ValueSet) VersionConvertorFactory_10_40.convertResource(reencoded, ADVISOR_10_40);
return valueSet;
} }
@Override @Override
@ -275,6 +282,16 @@ public class VersionCanonicalizer {
return (ConceptMap) VersionConvertorFactory_10_40.convertResource(reencoded, ADVISOR_10_40); return (ConceptMap) VersionConvertorFactory_10_40.convertResource(reencoded, ADVISOR_10_40);
} }
@Override
public SearchParameter searchParameterToCanonical(IBaseResource theSearchParameter) {
org.hl7.fhir.dstu2.model.SearchParameter reencoded = (org.hl7.fhir.dstu2.model.SearchParameter) reencodeToHl7Org(theSearchParameter);
SearchParameter retVal = (SearchParameter) VersionConvertorFactory_10_50.convertResource(reencoded, ADVISOR_10_50);
if (isBlank(retVal.getExpression())) {
retVal.setExpression(reencoded.getXpath());
}
return retVal;
}
private Resource reencodeToHl7Org(IBaseResource theInput) { private Resource reencodeToHl7Org(IBaseResource theInput) {
if (myHl7OrgStructures) { if (myHl7OrgStructures) {
return (Resource) theInput; return (Resource) theInput;
@ -291,11 +308,11 @@ public class VersionCanonicalizer {
} }
private class Dstu3Strategy implements IStrategy<org.hl7.fhir.dstu3.model.Resource> { private static class Dstu3Strategy implements IStrategy {
@Override @Override
public CapabilityStatement capabilityStatementToCanonical(org.hl7.fhir.dstu3.model.Resource theCapabilityStatement) { public CapabilityStatement capabilityStatementToCanonical(IBaseResource theCapabilityStatement) {
return (CapabilityStatement) VersionConvertorFactory_30_50.convertResource(theCapabilityStatement, ADVISOR_30_50); return (CapabilityStatement) VersionConvertorFactory_30_50.convertResource((org.hl7.fhir.dstu3.model.Resource) theCapabilityStatement, ADVISOR_30_50);
} }
@Override @Override
@ -327,12 +344,17 @@ public class VersionCanonicalizer {
public ConceptMap conceptMapToCanonical(IBaseResource theConceptMap) { public ConceptMap conceptMapToCanonical(IBaseResource theConceptMap) {
return (ConceptMap) VersionConvertorFactory_30_40.convertResource((org.hl7.fhir.dstu3.model.Resource) theConceptMap, ADVISOR_30_40); return (ConceptMap) VersionConvertorFactory_30_40.convertResource((org.hl7.fhir.dstu3.model.Resource) theConceptMap, ADVISOR_30_40);
} }
@Override
public SearchParameter searchParameterToCanonical(IBaseResource theSearchParameter) {
return (SearchParameter) VersionConvertorFactory_30_50.convertResource((org.hl7.fhir.dstu3.model.Resource) theSearchParameter, ADVISOR_30_50);
}
} }
private class R4Strategy implements IStrategy<org.hl7.fhir.r4.model.Resource> { private static class R4Strategy implements IStrategy {
@Override @Override
public CapabilityStatement capabilityStatementToCanonical(org.hl7.fhir.r4.model.Resource theCapabilityStatement) { public CapabilityStatement capabilityStatementToCanonical(IBaseResource theCapabilityStatement) {
return (CapabilityStatement) VersionConvertorFactory_40_50.convertResource(theCapabilityStatement, ADVISOR_40_50); return (CapabilityStatement) VersionConvertorFactory_40_50.convertResource((org.hl7.fhir.r4.model.Resource) theCapabilityStatement, ADVISOR_40_50);
} }
@Override @Override
@ -365,13 +387,18 @@ public class VersionCanonicalizer {
return (ConceptMap) theConceptMap; return (ConceptMap) theConceptMap;
} }
@Override
public SearchParameter searchParameterToCanonical(IBaseResource theSearchParameter) {
return (SearchParameter) VersionConvertorFactory_40_50.convertResource((org.hl7.fhir.r4.model.Resource) theSearchParameter, ADVISOR_40_50);
}
} }
private class R4BStrategy implements IStrategy<org.hl7.fhir.r4b.model.Resource> { private static class R4BStrategy implements IStrategy {
@Override @Override
public CapabilityStatement capabilityStatementToCanonical(org.hl7.fhir.r4b.model.Resource theCapabilityStatement) { public CapabilityStatement capabilityStatementToCanonical(IBaseResource theCapabilityStatement) {
return (CapabilityStatement) VersionConvertorFactory_43_50.convertResource(theCapabilityStatement, ADVISOR_43_50); return (CapabilityStatement) VersionConvertorFactory_43_50.convertResource((org.hl7.fhir.r4b.model.Resource) theCapabilityStatement, ADVISOR_43_50);
} }
@Override @Override
@ -410,13 +437,18 @@ public class VersionCanonicalizer {
return (ConceptMap) VersionConvertorFactory_40_50.convertResource(conceptMapR5, ADVISOR_40_50); return (ConceptMap) VersionConvertorFactory_40_50.convertResource(conceptMapR5, ADVISOR_40_50);
} }
@Override
public SearchParameter searchParameterToCanonical(IBaseResource theSearchParameter) {
return (SearchParameter) VersionConvertorFactory_43_50.convertResource((org.hl7.fhir.r4b.model.Resource) theSearchParameter, ADVISOR_43_50);
}
} }
private class R5Strategy implements IStrategy<org.hl7.fhir.r5.model.Resource> { private static class R5Strategy implements IStrategy {
@Override @Override
public CapabilityStatement capabilityStatementToCanonical(org.hl7.fhir.r5.model.Resource theCapabilityStatement) { public CapabilityStatement capabilityStatementToCanonical(IBaseResource theCapabilityStatement) {
return (CapabilityStatement) theCapabilityStatement; return (CapabilityStatement) theCapabilityStatement;
} }
@ -450,6 +482,11 @@ public class VersionCanonicalizer {
return (ConceptMap) VersionConvertorFactory_40_50.convertResource((org.hl7.fhir.r5.model.ConceptMap) theConceptMap, ADVISOR_40_50); return (ConceptMap) VersionConvertorFactory_40_50.convertResource((org.hl7.fhir.r5.model.ConceptMap) theConceptMap, ADVISOR_40_50);
} }
@Override
public SearchParameter searchParameterToCanonical(IBaseResource theSearchParameter) {
return (SearchParameter) theSearchParameter;
}
} }

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId> <artifactId>hapi-fhir</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -1,3 +1,3 @@
--- ---
release-date: "FILL ME" release-date: "2022-07-08"
codename: "Sojourner" codename: "Sojourner"

View File

@ -6,6 +6,7 @@
<ul> <ul>
<li>SLF4j (All): 1.7.33 -> 2.0.3</li> <li>SLF4j (All): 1.7.33 -> 2.0.3</li>
<li>Logback (All): 1.2.10 -> 1.4.4</li> <li>Logback (All): 1.2.10 -> 1.4.4</li>
<li>Woodstox-Core (XML Parser): 6.3.1 -> 6.4.0</li>
<li>log4j-to-slf4j (JPA): 2.17.1 -> 2.19.0</li> <li>log4j-to-slf4j (JPA): 2.17.1 -> 2.19.0</li>
<li>Jetty (CLI): 9.4.48.v20220622 -> 10.0.12</li> <li>Jetty (CLI): 9.4.48.v20220622 -> 10.0.12</li>
<li>Spring Boot: 2.7.4 -> 2.7.5</li> <li>Spring Boot: 2.7.4 -> 2.7.5</li>

View File

@ -2,13 +2,13 @@
The following diagram shows the request processing pipeline for processing a server request. You may click on the diagram to enlarge it. The following diagram shows the request processing pipeline for processing a server request. You may click on the diagram to enlarge it.
<a href="/hapi-fhir/docs/images/interceptors-server-pipeline.svg" target="_blank">Expand</a> <a href="server_pointcuts/interceptors-server-pipeline.svg" target="_blank">Expand</a>
<img src="/hapi-fhir/docs/images/interceptors-server-pipeline.svg" alt="Server Pipeline"/> <img src="server_pointcuts/interceptors-server-pipeline.svg" alt="Server Pipeline"/>
# Storage / JPA Server Pointcuts # Storage / JPA Server Pointcuts
The following diagram shows the request processing pipeline for processing a server request. You may click on the diagram to enlarge it. The following diagram shows the request processing pipeline for processing a server request. You may click on the diagram to enlarge it.
<a href="/hapi-fhir/docs/images/interceptors-server-jpa-pipeline.svg" target="_blank">Expand</a> <a href="server_pointcuts/interceptors-server-jpa-pipeline.svg" target="_blank">Expand</a>
<img src="/hapi-fhir/docs/images/interceptors-server-jpa-pipeline.svg" alt="Server Pipeline"/> <img src="server_pointcuts/interceptors-server-jpa-pipeline.svg" alt="Server Pipeline"/>

View File

@ -11,7 +11,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -84,7 +84,7 @@ public class JpaJobPersistenceImpl implements IJobPersistence {
} }
@Override @Override
@Transactional(propagation = Propagation.REQUIRES_NEW) @Transactional(propagation = Propagation.REQUIRED)
public String storeWorkChunk(BatchWorkChunk theBatchWorkChunk) { public String storeWorkChunk(BatchWorkChunk theBatchWorkChunk) {
Batch2WorkChunkEntity entity = new Batch2WorkChunkEntity(); Batch2WorkChunkEntity entity = new Batch2WorkChunkEntity();
entity.setId(UUID.randomUUID().toString()); entity.setId(UUID.randomUUID().toString());
@ -102,7 +102,7 @@ public class JpaJobPersistenceImpl implements IJobPersistence {
} }
@Override @Override
@Transactional(propagation = Propagation.REQUIRES_NEW) @Transactional(propagation = Propagation.REQUIRED)
public Optional<WorkChunk> fetchWorkChunkSetStartTimeAndMarkInProgress(String theChunkId) { public Optional<WorkChunk> fetchWorkChunkSetStartTimeAndMarkInProgress(String theChunkId) {
myWorkChunkRepository.updateChunkStatusForStart(theChunkId, new Date(), StatusEnum.IN_PROGRESS); myWorkChunkRepository.updateChunkStatusForStart(theChunkId, new Date(), StatusEnum.IN_PROGRESS);
Optional<Batch2WorkChunkEntity> chunk = myWorkChunkRepository.findById(theChunkId); Optional<Batch2WorkChunkEntity> chunk = myWorkChunkRepository.findById(theChunkId);
@ -110,7 +110,7 @@ public class JpaJobPersistenceImpl implements IJobPersistence {
} }
@Override @Override
@Transactional(propagation = Propagation.REQUIRES_NEW) @Transactional(propagation = Propagation.REQUIRED)
public String storeNewInstance(JobInstance theInstance) { public String storeNewInstance(JobInstance theInstance) {
Validate.isTrue(isBlank(theInstance.getInstanceId())); Validate.isTrue(isBlank(theInstance.getInstanceId()));
@ -271,7 +271,7 @@ public class JpaJobPersistenceImpl implements IJobPersistence {
} }
@Override @Override
@Transactional(propagation = Propagation.REQUIRES_NEW) @Transactional(propagation = Propagation.REQUIRED)
public boolean canAdvanceInstanceToNextStep(String theInstanceId, String theCurrentStepId) { public boolean canAdvanceInstanceToNextStep(String theInstanceId, String theCurrentStepId) {
List<StatusEnum> statusesForStep = myWorkChunkRepository.getDistinctStatusesForStep(theInstanceId, theCurrentStepId); List<StatusEnum> statusesForStep = myWorkChunkRepository.getDistinctStatusesForStep(theInstanceId, theCurrentStepId);
ourLog.debug("Checking whether gated job can advanced to next step. [instanceId={}, currentStepId={}, statusesForStep={}]", theInstanceId, theCurrentStepId, statusesForStep); ourLog.debug("Checking whether gated job can advanced to next step. [instanceId={}, currentStepId={}, statusesForStep={}]", theInstanceId, theCurrentStepId, statusesForStep);

View File

@ -27,6 +27,7 @@ import ca.uhn.fhir.jpa.dao.HistoryBuilderFactory;
import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc; import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
import ca.uhn.fhir.jpa.dao.ISearchBuilder; import ca.uhn.fhir.jpa.dao.ISearchBuilder;
import ca.uhn.fhir.jpa.dao.MatchResourceUrlService; import ca.uhn.fhir.jpa.dao.MatchResourceUrlService;
import ca.uhn.fhir.jpa.dao.ObservationLastNIndexPersistSvc;
import ca.uhn.fhir.jpa.dao.SearchBuilderFactory; import ca.uhn.fhir.jpa.dao.SearchBuilderFactory;
import ca.uhn.fhir.jpa.dao.TransactionProcessor; import ca.uhn.fhir.jpa.dao.TransactionProcessor;
import ca.uhn.fhir.jpa.dao.expunge.ExpungeEverythingService; import ca.uhn.fhir.jpa.dao.expunge.ExpungeEverythingService;
@ -116,10 +117,14 @@ import ca.uhn.fhir.jpa.searchparam.nickname.NicknameInterceptor;
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamProvider; import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamProvider;
import ca.uhn.fhir.jpa.sp.ISearchParamPresenceSvc; import ca.uhn.fhir.jpa.sp.ISearchParamPresenceSvc;
import ca.uhn.fhir.jpa.sp.SearchParamPresenceSvcImpl; import ca.uhn.fhir.jpa.sp.SearchParamPresenceSvcImpl;
import ca.uhn.fhir.jpa.term.TermCodeSystemStorageSvcImpl;
import ca.uhn.fhir.jpa.term.TermConceptMappingSvcImpl; import ca.uhn.fhir.jpa.term.TermConceptMappingSvcImpl;
import ca.uhn.fhir.jpa.term.TermReadSvcImpl; import ca.uhn.fhir.jpa.term.TermReadSvcImpl;
import ca.uhn.fhir.jpa.term.TermReindexingSvcImpl;
import ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc;
import ca.uhn.fhir.jpa.term.api.ITermConceptMappingSvc; import ca.uhn.fhir.jpa.term.api.ITermConceptMappingSvc;
import ca.uhn.fhir.jpa.term.api.ITermReadSvc; import ca.uhn.fhir.jpa.term.api.ITermReadSvc;
import ca.uhn.fhir.jpa.term.api.ITermReindexingSvc;
import ca.uhn.fhir.jpa.term.config.TermCodeSystemConfig; import ca.uhn.fhir.jpa.term.config.TermCodeSystemConfig;
import ca.uhn.fhir.jpa.util.MemoryCacheService; import ca.uhn.fhir.jpa.util.MemoryCacheService;
import ca.uhn.fhir.jpa.validation.ResourceLoaderImpl; import ca.uhn.fhir.jpa.validation.ResourceLoaderImpl;
@ -763,4 +768,22 @@ public class JpaConfig {
return new TermReadSvcImpl(); return new TermReadSvcImpl();
} }
@Bean
public ITermCodeSystemStorageSvc termCodeSystemStorageSvc() {
return new TermCodeSystemStorageSvcImpl();
}
@Bean
public ITermReindexingSvc termReindexingSvc() {
return new TermReindexingSvcImpl();
}
@Bean
public ObservationLastNIndexPersistSvc baseObservationLastNIndexpersistSvc() {
return new ObservationLastNIndexPersistSvc();
}
} }

View File

@ -1,55 +0,0 @@
package ca.uhn.fhir.jpa.config;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.jpa.dao.ObservationLastNIndexPersistSvc;
import ca.uhn.fhir.jpa.term.TermCodeSystemStorageSvcImpl;
import ca.uhn.fhir.jpa.term.TermConceptDaoSvc;
import ca.uhn.fhir.jpa.term.TermDeferredStorageSvcImpl;
import ca.uhn.fhir.jpa.term.TermReindexingSvcImpl;
import ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc;
import ca.uhn.fhir.jpa.term.api.ITermDeferredStorageSvc;
import ca.uhn.fhir.jpa.term.api.ITermReindexingSvc;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SharedConfigDstu3Plus {
@Bean
public ITermCodeSystemStorageSvc termCodeSystemStorageSvc() {
return new TermCodeSystemStorageSvcImpl();
}
@Bean
public ITermReindexingSvc termReindexingSvc() {
return new TermReindexingSvcImpl();
}
@Bean
public ObservationLastNIndexPersistSvc baseObservationLastNIndexpersistSvc() {
return new ObservationLastNIndexPersistSvc();
}
}

View File

@ -6,7 +6,6 @@ import ca.uhn.fhir.jpa.api.IDaoRegistry;
import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao; import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao;
import ca.uhn.fhir.jpa.config.GeneratedDaoAndResourceProviderConfigDstu3; import ca.uhn.fhir.jpa.config.GeneratedDaoAndResourceProviderConfigDstu3;
import ca.uhn.fhir.jpa.config.JpaConfig; import ca.uhn.fhir.jpa.config.JpaConfig;
import ca.uhn.fhir.jpa.config.SharedConfigDstu3Plus;
import ca.uhn.fhir.jpa.dao.ITransactionProcessorVersionAdapter; import ca.uhn.fhir.jpa.dao.ITransactionProcessorVersionAdapter;
import ca.uhn.fhir.jpa.dao.dstu3.TransactionProcessorVersionAdapterDstu3; import ca.uhn.fhir.jpa.dao.dstu3.TransactionProcessorVersionAdapterDstu3;
import ca.uhn.fhir.jpa.graphql.GraphQLProvider; import ca.uhn.fhir.jpa.graphql.GraphQLProvider;
@ -53,7 +52,6 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
@Import({ @Import({
FhirContextDstu3Config.class, FhirContextDstu3Config.class,
GeneratedDaoAndResourceProviderConfigDstu3.class, GeneratedDaoAndResourceProviderConfigDstu3.class,
SharedConfigDstu3Plus.class,
JpaConfig.class JpaConfig.class
}) })
public class JpaDstu3Config { public class JpaDstu3Config {

View File

@ -7,7 +7,6 @@ import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao; import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao;
import ca.uhn.fhir.jpa.config.GeneratedDaoAndResourceProviderConfigR4; import ca.uhn.fhir.jpa.config.GeneratedDaoAndResourceProviderConfigR4;
import ca.uhn.fhir.jpa.config.JpaConfig; import ca.uhn.fhir.jpa.config.JpaConfig;
import ca.uhn.fhir.jpa.config.SharedConfigDstu3Plus;
import ca.uhn.fhir.jpa.dao.ITransactionProcessorVersionAdapter; import ca.uhn.fhir.jpa.dao.ITransactionProcessorVersionAdapter;
import ca.uhn.fhir.jpa.dao.r4.TransactionProcessorVersionAdapterR4; import ca.uhn.fhir.jpa.dao.r4.TransactionProcessorVersionAdapterR4;
import ca.uhn.fhir.jpa.graphql.GraphQLProvider; import ca.uhn.fhir.jpa.graphql.GraphQLProvider;
@ -22,7 +21,6 @@ import ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc;
import ca.uhn.fhir.jpa.term.api.ITermDeferredStorageSvc; import ca.uhn.fhir.jpa.term.api.ITermDeferredStorageSvc;
import ca.uhn.fhir.jpa.term.api.ITermLoaderSvc; import ca.uhn.fhir.jpa.term.api.ITermLoaderSvc;
import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc; import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc;
import ca.uhn.fhir.rest.server.provider.ResourceProviderFactory;
import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.rest.server.util.ISearchParamRegistry;
import org.hl7.fhir.r4.model.Bundle; import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.Consent; import org.hl7.fhir.r4.model.Consent;
@ -62,7 +60,6 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
@Import({ @Import({
FhirContextR4Config.class, FhirContextR4Config.class,
GeneratedDaoAndResourceProviderConfigR4.class, GeneratedDaoAndResourceProviderConfigR4.class,
SharedConfigDstu3Plus.class,
JpaConfig.class JpaConfig.class
}) })
public class JpaR4Config { public class JpaR4Config {

View File

@ -6,7 +6,6 @@ import ca.uhn.fhir.jpa.api.IDaoRegistry;
import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao; import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao;
import ca.uhn.fhir.jpa.config.GeneratedDaoAndResourceProviderConfigR4B; import ca.uhn.fhir.jpa.config.GeneratedDaoAndResourceProviderConfigR4B;
import ca.uhn.fhir.jpa.config.JpaConfig; import ca.uhn.fhir.jpa.config.JpaConfig;
import ca.uhn.fhir.jpa.config.SharedConfigDstu3Plus;
import ca.uhn.fhir.jpa.dao.ITransactionProcessorVersionAdapter; import ca.uhn.fhir.jpa.dao.ITransactionProcessorVersionAdapter;
import ca.uhn.fhir.jpa.dao.r4b.TransactionProcessorVersionAdapterR4B; import ca.uhn.fhir.jpa.dao.r4b.TransactionProcessorVersionAdapterR4B;
import ca.uhn.fhir.jpa.graphql.GraphQLProvider; import ca.uhn.fhir.jpa.graphql.GraphQLProvider;
@ -53,7 +52,6 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
@Import({ @Import({
FhirContextR4BConfig.class, FhirContextR4BConfig.class,
GeneratedDaoAndResourceProviderConfigR4B.class, GeneratedDaoAndResourceProviderConfigR4B.class,
SharedConfigDstu3Plus.class,
JpaConfig.class JpaConfig.class
}) })
public class JpaR4BConfig { public class JpaR4BConfig {

View File

@ -6,7 +6,6 @@ import ca.uhn.fhir.jpa.api.IDaoRegistry;
import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao; import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao;
import ca.uhn.fhir.jpa.config.GeneratedDaoAndResourceProviderConfigR5; import ca.uhn.fhir.jpa.config.GeneratedDaoAndResourceProviderConfigR5;
import ca.uhn.fhir.jpa.config.JpaConfig; import ca.uhn.fhir.jpa.config.JpaConfig;
import ca.uhn.fhir.jpa.config.SharedConfigDstu3Plus;
import ca.uhn.fhir.jpa.dao.ITransactionProcessorVersionAdapter; import ca.uhn.fhir.jpa.dao.ITransactionProcessorVersionAdapter;
import ca.uhn.fhir.jpa.dao.r5.TransactionProcessorVersionAdapterR5; import ca.uhn.fhir.jpa.dao.r5.TransactionProcessorVersionAdapterR5;
import ca.uhn.fhir.jpa.graphql.GraphQLProvider; import ca.uhn.fhir.jpa.graphql.GraphQLProvider;
@ -53,7 +52,6 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
@Import({ @Import({
FhirContextR5Config.class, FhirContextR5Config.class,
GeneratedDaoAndResourceProviderConfigR5.class, GeneratedDaoAndResourceProviderConfigR5.class,
SharedConfigDstu3Plus.class,
JpaConfig.class JpaConfig.class
}) })
public class JpaR5Config { public class JpaR5Config {

View File

@ -1,42 +0,0 @@
package ca.uhn.fhir.jpa.dao;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoComposition;
import ca.uhn.fhir.model.dstu2.resource.Composition;
import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.server.exceptions.NotImplementedOperationException;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import javax.servlet.http.HttpServletRequest;
public class FhirResourceDaoCompositionDstu2 extends BaseHapiFhirResourceDao<Composition>implements IFhirResourceDaoComposition<Composition> {
@Override
public IBundleProvider getDocumentForComposition(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdate, SortSpec theSort, RequestDetails theRequestDetails) {
throw new NotImplementedOperationException(Msg.code(955) + "$document not implemented in DSTU2");
}
}

View File

@ -1,89 +0,0 @@
package ca.uhn.fhir.jpa.dao;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoSearchParameter;
import ca.uhn.fhir.jpa.dao.r4.FhirResourceDaoSearchParameterR4;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.searchparam.extractor.ISearchParamExtractor;
import ca.uhn.fhir.model.dstu2.resource.SearchParameter;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import com.google.common.collect.Lists;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_10_40;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_10_40;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
public class FhirResourceDaoSearchParameterDstu2 extends BaseHapiFhirResourceDao<SearchParameter> implements IFhirResourceDaoSearchParameter<SearchParameter> {
@Autowired
private ISearchParamExtractor mySearchParamExtractor;
private FhirContext myDstu2Hl7OrgContext = FhirContext.forDstu2Hl7Org();
protected void reindexAffectedResources(SearchParameter theResource, RequestDetails theRequestDetails) {
Boolean reindex = theResource != null ? CURRENTLY_REINDEXING.get(theResource) : null;
String expression = theResource != null ? theResource.getXpath() : null;
List<String> base = theResource != null ? Lists.newArrayList(theResource.getBase()) : null;
requestReindexForRelatedResources(reindex, base, theRequestDetails);
}
@Override
protected void postPersist(ResourceTable theEntity, SearchParameter theResource, RequestDetails theRequestDetails) {
super.postPersist(theEntity, theResource, theRequestDetails);
reindexAffectedResources(theResource, theRequestDetails);
}
@Override
protected void postUpdate(ResourceTable theEntity, SearchParameter theResource, RequestDetails theRequestDetails) {
super.postUpdate(theEntity, theResource, theRequestDetails);
reindexAffectedResources(theResource, theRequestDetails);
}
@Override
protected void preDelete(SearchParameter theResourceToDelete, ResourceTable theEntityToDelete, RequestDetails theRequestDetails) {
super.preDelete(theResourceToDelete, theEntityToDelete, theRequestDetails);
reindexAffectedResources(theResourceToDelete, theRequestDetails);
}
@Override
protected void validateResourceForStorage(SearchParameter theResource, ResourceTable theEntityToSave) {
super.validateResourceForStorage(theResource, theEntityToSave);
String encoded = getContext().newJsonParser().encodeResourceToString(theResource);
org.hl7.fhir.dstu2.model.SearchParameter hl7Org = myDstu2Hl7OrgContext.newJsonParser().parseResource(org.hl7.fhir.dstu2.model.SearchParameter.class, encoded);
org.hl7.fhir.r4.model.SearchParameter convertedSp = (org.hl7.fhir.r4.model.SearchParameter) VersionConvertorFactory_10_40.convertResource(hl7Org, new BaseAdvisor_10_40(false));
if (isBlank(convertedSp.getExpression()) && isNotBlank(hl7Org.getXpath())) {
convertedSp.setExpression(hl7Org.getXpath());
}
FhirResourceDaoSearchParameterR4.validateSearchParam(convertedSp, getContext(), getConfig(), mySearchParamRegistry, mySearchParamExtractor);
}
}

View File

@ -1,4 +1,4 @@
package ca.uhn.fhir.jpa.dao.r4; package ca.uhn.fhir.jpa.dao;
/* /*
* #%L * #%L
@ -21,7 +21,6 @@ package ca.uhn.fhir.jpa.dao.r4;
*/ */
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoComposition; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoComposition;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.rest.api.SortSpec; import ca.uhn.fhir.rest.api.SortSpec;
@ -29,6 +28,7 @@ import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.DateRangeParam; import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.param.StringParam; import ca.uhn.fhir.rest.param.StringParam;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IPrimitiveType; import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.hl7.fhir.r4.model.Composition; import org.hl7.fhir.r4.model.Composition;
@ -36,7 +36,7 @@ import org.hl7.fhir.r4.model.Composition;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.Collections; import java.util.Collections;
public class FhirResourceDaoCompositionR4 extends BaseHapiFhirResourceDao<Composition> implements IFhirResourceDaoComposition<Composition> { public class JpaResourceDaoComposition<T extends IBaseResource> extends BaseHapiFhirResourceDao<T> implements IFhirResourceDaoComposition<T> {
@Override @Override
public IBundleProvider getDocumentForComposition(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdate, SortSpec theSort, RequestDetails theRequestDetails) { public IBundleProvider getDocumentForComposition(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdate, SortSpec theSort, RequestDetails theRequestDetails) {

View File

@ -28,30 +28,71 @@ import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.partition.IRequestPartitionHelperSvc; import ca.uhn.fhir.jpa.partition.IRequestPartitionHelperSvc;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.model.api.IQueryParameterType; import ca.uhn.fhir.model.api.IQueryParameterType;
import ca.uhn.fhir.rest.api.CacheControlDirective;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.SortOrderEnum; import ca.uhn.fhir.rest.api.SortOrderEnum;
import ca.uhn.fhir.rest.api.SortSpec; import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails; import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
import ca.uhn.fhir.rest.param.ReferenceOrListParam; import ca.uhn.fhir.rest.param.ReferenceOrListParam;
import ca.uhn.fhir.rest.param.ReferenceParam; import ca.uhn.fhir.rest.param.ReferenceParam;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.Observation;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.support.TransactionTemplate; import org.springframework.transaction.support.TransactionTemplate;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.TreeMap; import java.util.TreeMap;
public abstract class BaseHapiFhirResourceDaoObservation<T extends IBaseResource> extends BaseHapiFhirResourceDao<T> implements IFhirResourceDaoObservation<T> { public class JpaResourceDaoObservation<T extends IBaseResource> extends BaseHapiFhirResourceDao<T> implements IFhirResourceDaoObservation<T> {
@PersistenceContext(type = PersistenceContextType.TRANSACTION)
protected EntityManager myEntityManager;
@Autowired @Autowired
ObservationLastNIndexPersistSvc myObservationLastNIndexPersistSvc; ObservationLastNIndexPersistSvc myObservationLastNIndexPersistSvc;
@Autowired @Autowired
private IRequestPartitionHelperSvc myRequestPartitionHelperService; private IRequestPartitionHelperSvc myRequestPartitionHelperService;
@Override
public IBundleProvider observationsLastN(SearchParameterMap theSearchParameterMap, RequestDetails theRequestDetails, HttpServletResponse theServletResponse) {
updateSearchParamsForLastn(theSearchParameterMap, theRequestDetails);
RequestPartitionId requestPartitionId = myRequestPartitionHelperService.determineReadPartitionForRequestForSearchType(theRequestDetails, getResourceName(), theSearchParameterMap, null);
return mySearchCoordinatorSvc.registerSearch(this, theSearchParameterMap, getResourceName(), new CacheControlDirective().parse(theRequestDetails.getHeaders(Constants.HEADER_CACHE_CONTROL)), theRequestDetails, requestPartitionId);
}
private String getEffectiveParamName() {
return Observation.SP_DATE;
}
private String getCodeParamName() {
return Observation.SP_CODE;
}
private String getSubjectParamName() {
return Observation.SP_SUBJECT;
}
private String getPatientParamName() {
return Observation.SP_PATIENT;
}
@Override
public ResourceTable updateEntity(RequestDetails theRequest, IBaseResource theResource, IBasePersistedResource theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing,
boolean theUpdateVersion, TransactionDetails theTransactionDetails, boolean theForceUpdate, boolean theCreateNewHistoryEntry) {
return updateObservationEntity(theRequest, theResource, theEntity, theDeletedTimestampOrNull,
thePerformIndexing, theUpdateVersion, theTransactionDetails, theForceUpdate,
theCreateNewHistoryEntry);
}
protected ResourceTable updateObservationEntity(RequestDetails theRequest, IBaseResource theResource, IBasePersistedResource theEntity, protected ResourceTable updateObservationEntity(RequestDetails theRequest, IBaseResource theResource, IBasePersistedResource theEntity,
Date theDeletedTimestampOrNull, boolean thePerformIndexing, boolean theUpdateVersion, Date theDeletedTimestampOrNull, boolean thePerformIndexing, boolean theUpdateVersion,
TransactionDetails theTransactionDetails, boolean theForceUpdate, boolean theCreateNewHistoryEntry) { TransactionDetails theTransactionDetails, boolean theForceUpdate, boolean theCreateNewHistoryEntry) {
@ -130,12 +171,4 @@ public abstract class BaseHapiFhirResourceDaoObservation<T extends IBaseResource
} }
abstract protected String getEffectiveParamName();
abstract protected String getCodeParamName();
abstract protected String getSubjectParamName();
abstract protected String getPatientParamName();
} }

View File

@ -1,4 +1,4 @@
package ca.uhn.fhir.jpa.dao.r4; package ca.uhn.fhir.jpa.dao;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.context.FhirVersionEnum;
@ -6,18 +6,18 @@ import ca.uhn.fhir.context.RuntimeSearchParam;
import ca.uhn.fhir.i18n.Msg; import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.api.config.DaoConfig; import ca.uhn.fhir.jpa.api.config.DaoConfig;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoSearchParameter; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoSearchParameter;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.searchparam.extractor.ISearchParamExtractor;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException; import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.fhir.rest.server.util.ISearchParamRegistry;
import ca.uhn.fhir.util.ElementUtil; import ca.uhn.fhir.util.ElementUtil;
import ca.uhn.fhir.util.HapiExtensions; import ca.uhn.fhir.util.HapiExtensions;
import ca.uhn.hapi.converters.canonical.VersionCanonicalizer;
import com.google.common.annotations.VisibleForTesting;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IPrimitiveType; import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.hl7.fhir.r4.model.CodeType; import org.hl7.fhir.r5.model.CodeType;
import org.hl7.fhir.r4.model.Enumerations; import org.hl7.fhir.r5.model.Enumerations;
import org.hl7.fhir.r4.model.SearchParameter; import org.hl7.fhir.r5.model.SearchParameter;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import java.util.List; import java.util.List;
@ -46,60 +46,63 @@ import static org.apache.commons.lang3.StringUtils.isBlank;
* #L% * #L%
*/ */
public class FhirResourceDaoSearchParameterR4 extends BaseHapiFhirResourceDao<SearchParameter> implements IFhirResourceDaoSearchParameter<SearchParameter> { public class JpaResourceDaoSearchParameter<T extends IBaseResource> extends BaseHapiFhirResourceDao<T> implements IFhirResourceDaoSearchParameter<T> {
private static final Pattern REGEX_SP_EXPRESSION_HAS_PATH = Pattern.compile("[( ]*([A-Z][a-zA-Z]+\\.)?[a-z].*"); private static final Pattern REGEX_SP_EXPRESSION_HAS_PATH = Pattern.compile("[( ]*([A-Z][a-zA-Z]+\\.)?[a-z].*");
@Autowired @Autowired
private ISearchParamExtractor mySearchParamExtractor; private VersionCanonicalizer myVersionCanonicalizer;
protected void reindexAffectedResources(SearchParameter theResource, RequestDetails theRequestDetails) { protected void reindexAffectedResources(T theResource, RequestDetails theRequestDetails) {
// N.B. Don't do this on the canonicalized version
Boolean reindex = theResource != null ? CURRENTLY_REINDEXING.get(theResource) : null; Boolean reindex = theResource != null ? CURRENTLY_REINDEXING.get(theResource) : null;
String expression = theResource != null ? theResource.getExpression() : null;
List<String> base = theResource != null ? theResource.getBase().stream().map(CodeType::getCode).collect(Collectors.toList()) : null; org.hl7.fhir.r5.model.SearchParameter searchParameter = myVersionCanonicalizer.searchParameterToCanonical(theResource);
List<String> base = theResource != null ? searchParameter.getBase().stream().map(CodeType::getCode).collect(Collectors.toList()) : null;
requestReindexForRelatedResources(reindex, base, theRequestDetails); requestReindexForRelatedResources(reindex, base, theRequestDetails);
} }
@Override @Override
protected void postPersist(ResourceTable theEntity, SearchParameter theResource, RequestDetails theRequestDetails) { protected void postPersist(ResourceTable theEntity, T theResource, RequestDetails theRequestDetails) {
super.postPersist(theEntity, theResource, theRequestDetails); super.postPersist(theEntity, theResource, theRequestDetails);
reindexAffectedResources(theResource, theRequestDetails); reindexAffectedResources(theResource, theRequestDetails);
} }
@Override @Override
protected void postUpdate(ResourceTable theEntity, SearchParameter theResource, RequestDetails theRequestDetails) { protected void postUpdate(ResourceTable theEntity, T theResource, RequestDetails theRequestDetails) {
super.postUpdate(theEntity, theResource, theRequestDetails); super.postUpdate(theEntity, theResource, theRequestDetails);
reindexAffectedResources(theResource, theRequestDetails); reindexAffectedResources(theResource, theRequestDetails);
} }
@Override @Override
protected void preDelete(SearchParameter theResourceToDelete, ResourceTable theEntityToDelete, RequestDetails theRequestDetails) { protected void preDelete(T theResourceToDelete, ResourceTable theEntityToDelete, RequestDetails theRequestDetails) {
super.preDelete(theResourceToDelete, theEntityToDelete, theRequestDetails); super.preDelete(theResourceToDelete, theEntityToDelete, theRequestDetails);
reindexAffectedResources(theResourceToDelete, theRequestDetails); reindexAffectedResources(theResourceToDelete, theRequestDetails);
} }
@Override @Override
protected void validateResourceForStorage(SearchParameter theResource, ResourceTable theEntityToSave) { protected void validateResourceForStorage(T theResource, ResourceTable theEntityToSave) {
super.validateResourceForStorage(theResource, theEntityToSave); super.validateResourceForStorage(theResource, theEntityToSave);
validateSearchParam(theResource, getContext(), getConfig(), mySearchParamRegistry, mySearchParamExtractor); validateSearchParam(theResource, getContext(), getConfig());
} }
public static void validateSearchParam(SearchParameter theResource, FhirContext theContext, DaoConfig theDaoConfig, ISearchParamRegistry theSearchParamRegistry, ISearchParamExtractor theSearchParamExtractor) { public void validateSearchParam(IBaseResource theResource, FhirContext theContext, DaoConfig theDaoConfig) {
org.hl7.fhir.r5.model.SearchParameter searchParameter = myVersionCanonicalizer.searchParameterToCanonical(theResource);
/* /*
* If overriding built-in SPs is disabled on this server, make sure we aren't * If overriding built-in SPs is disabled on this server, make sure we aren't
* doing that * doing that
*/ */
if (theDaoConfig.getModelConfig().isDefaultSearchParamsCanBeOverridden() == false) { if (theDaoConfig.getModelConfig().isDefaultSearchParamsCanBeOverridden() == false) {
for (IPrimitiveType<?> nextBaseType : theResource.getBase()) { for (IPrimitiveType<?> nextBaseType : searchParameter.getBase()) {
String nextBase = nextBaseType.getValueAsString(); String nextBase = nextBaseType.getValueAsString();
RuntimeSearchParam existingSearchParam = theSearchParamRegistry.getActiveSearchParam(nextBase, theResource.getCode()); RuntimeSearchParam existingSearchParam = mySearchParamRegistry.getActiveSearchParam(nextBase, searchParameter.getCode());
if (existingSearchParam != null) { if (existingSearchParam != null) {
boolean isBuiltIn = existingSearchParam.getId() == null; boolean isBuiltIn = existingSearchParam.getId() == null;
isBuiltIn |= existingSearchParam.getUri().startsWith("http://hl7.org/fhir/SearchParameter/"); isBuiltIn |= existingSearchParam.getUri().startsWith("http://hl7.org/fhir/SearchParameter/");
if (isBuiltIn) { if (isBuiltIn) {
throw new UnprocessableEntityException(Msg.code(1111) + "Can not override built-in search parameter " + nextBase + ":" + theResource.getCode() + " because overriding is disabled on this server"); throw new UnprocessableEntityException(Msg.code(1111) + "Can not override built-in search parameter " + nextBase + ":" + searchParameter.getCode() + " because overriding is disabled on this server");
} }
} }
} }
@ -109,34 +112,34 @@ public class FhirResourceDaoSearchParameterR4 extends BaseHapiFhirResourceDao<Se
* Everything below is validating that the SP is actually valid. We'll only do that if the * Everything below is validating that the SP is actually valid. We'll only do that if the
* SPO is active, so that we don't block people from uploading works-in-progress * SPO is active, so that we don't block people from uploading works-in-progress
*/ */
if (theResource.getStatus() == null) { if (searchParameter.getStatus() == null) {
throw new UnprocessableEntityException(Msg.code(1112) + "SearchParameter.status is missing or invalid"); throw new UnprocessableEntityException(Msg.code(1112) + "SearchParameter.status is missing or invalid");
} }
if (!theResource.getStatus().name().equals("ACTIVE")) { if (!searchParameter.getStatus().name().equals("ACTIVE")) {
return; return;
} }
if (ElementUtil.isEmpty(theResource.getBase()) && (theResource.getType() == null || !Enumerations.SearchParamType.COMPOSITE.name().equals(theResource.getType().name()))) { if (ElementUtil.isEmpty(searchParameter.getBase()) && (searchParameter.getType() == null || !Enumerations.SearchParamType.COMPOSITE.name().equals(searchParameter.getType().name()))) {
throw new UnprocessableEntityException(Msg.code(1113) + "SearchParameter.base is missing"); throw new UnprocessableEntityException(Msg.code(1113) + "SearchParameter.base is missing");
} }
boolean isUnique = hasAnyExtensionUniqueSetTo(theResource, true); boolean isUnique = hasAnyExtensionUniqueSetTo(searchParameter, true);
if (theResource.getType() != null && theResource.getType().name().equals(Enumerations.SearchParamType.COMPOSITE.name()) && isBlank(theResource.getExpression())) { if (searchParameter.getType() != null && searchParameter.getType().name().equals(Enumerations.SearchParamType.COMPOSITE.name()) && isBlank(searchParameter.getExpression())) {
// this is ok // this is ok
} else if (isBlank(theResource.getExpression())) { } else if (isBlank(searchParameter.getExpression())) {
throw new UnprocessableEntityException(Msg.code(1114) + "SearchParameter.expression is missing"); throw new UnprocessableEntityException(Msg.code(1114) + "SearchParameter.expression is missing");
} else { } else {
if (isUnique) { if (isUnique) {
if (theResource.getComponent().size() == 0) { if (searchParameter.getComponent().size() == 0) {
throw new UnprocessableEntityException(Msg.code(1115) + "SearchParameter is marked as unique but has no components"); throw new UnprocessableEntityException(Msg.code(1115) + "SearchParameter is marked as unique but has no components");
} }
for (SearchParameter.SearchParameterComponentComponent next : theResource.getComponent()) { for (SearchParameter.SearchParameterComponentComponent next : searchParameter.getComponent()) {
if (isBlank(next.getDefinition())) { if (isBlank(next.getDefinition())) {
throw new UnprocessableEntityException(Msg.code(1116) + "SearchParameter is marked as unique but is missing component.definition"); throw new UnprocessableEntityException(Msg.code(1116) + "SearchParameter is marked as unique but is missing component.definition");
} }
@ -146,14 +149,13 @@ public class FhirResourceDaoSearchParameterR4 extends BaseHapiFhirResourceDao<Se
FhirVersionEnum fhirVersion = theContext.getVersion().getVersion(); FhirVersionEnum fhirVersion = theContext.getVersion().getVersion();
if (fhirVersion.isOlderThan(FhirVersionEnum.DSTU3)) { if (fhirVersion.isOlderThan(FhirVersionEnum.DSTU3)) {
// omitting validation for DSTU2_HL7ORG, DSTU2_1 and DSTU2 // omitting validation for DSTU2_HL7ORG, DSTU2_1 and DSTU2
} } else {
else {
if (theDaoConfig.isValidateSearchParameterExpressionsOnSave()) { if (theDaoConfig.isValidateSearchParameterExpressionsOnSave()) {
validateExpressionPath(theResource); validateExpressionPath(searchParameter);
String expression = getExpression(theResource); String expression = getExpression(searchParameter);
try { try {
theContext.newFhirPath().parse(expression); theContext.newFhirPath().parse(expression);
@ -166,7 +168,12 @@ public class FhirResourceDaoSearchParameterR4 extends BaseHapiFhirResourceDao<Se
} }
private static void validateExpressionPath(SearchParameter theSearchParameter){ @VisibleForTesting
void setVersionCanonicalizerForUnitTest(VersionCanonicalizer theVersionCanonicalizer) {
myVersionCanonicalizer = theVersionCanonicalizer;
}
private static void validateExpressionPath(SearchParameter theSearchParameter) {
String expression = getExpression(theSearchParameter); String expression = getExpression(theSearchParameter);
boolean isResourceOfTypeComposite = theSearchParameter.getType() == Enumerations.SearchParamType.COMPOSITE; boolean isResourceOfTypeComposite = theSearchParameter.getType() == Enumerations.SearchParamType.COMPOSITE;
@ -175,23 +182,23 @@ public class FhirResourceDaoSearchParameterR4 extends BaseHapiFhirResourceDao<Se
boolean isUnique = hasAnyExtensionUniqueSetTo(theSearchParameter, true); boolean isUnique = hasAnyExtensionUniqueSetTo(theSearchParameter, true);
if ( !isUnique && !isResourceOfTypeComposite && !isResourceOfTypeSpecial && !expressionHasPath ) { if (!isUnique && !isResourceOfTypeComposite && !isResourceOfTypeSpecial && !expressionHasPath) {
throw new UnprocessableEntityException(Msg.code(1120) + "SearchParameter.expression value \"" + expression + "\" is invalid due to missing/incorrect path"); throw new UnprocessableEntityException(Msg.code(1120) + "SearchParameter.expression value \"" + expression + "\" is invalid due to missing/incorrect path");
} }
} }
private static String getExpression(SearchParameter theSearchParameter){ private static String getExpression(SearchParameter theSearchParameter) {
return theSearchParameter.getExpression().trim(); return theSearchParameter.getExpression().trim();
} }
private static boolean hasAnyExtensionUniqueSetTo(SearchParameter theSearchParameter, boolean theValue){ private static boolean hasAnyExtensionUniqueSetTo(SearchParameter theSearchParameter, boolean theValue) {
String theValueAsString = Boolean.toString(theValue); String theValueAsString = Boolean.toString(theValue);
return theSearchParameter return theSearchParameter
.getExtensionsByUrl(HapiExtensions.EXT_SP_UNIQUE) .getExtensionsByUrl(HapiExtensions.EXT_SP_UNIQUE)
.stream() .stream()
.anyMatch(t-> theValueAsString.equals(t.getValueAsPrimitive().getValueAsString())); .anyMatch(t -> theValueAsString.equals(t.getValueAsPrimitive().getValueAsString()));
} }
} }

View File

@ -1,59 +0,0 @@
package ca.uhn.fhir.jpa.dao.dstu3;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoComposition;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.param.StringParam;
import org.hl7.fhir.dstu3.model.Composition;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import javax.servlet.http.HttpServletRequest;
import java.util.Collections;
public class FhirResourceDaoCompositionDstu3 extends BaseHapiFhirResourceDao<Composition> implements IFhirResourceDaoComposition<Composition> {
@Override
public IBundleProvider getDocumentForComposition(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdate, SortSpec theSort, RequestDetails theRequestDetails) {
SearchParameterMap paramMap = new SearchParameterMap();
if (theCount != null) {
paramMap.setCount(theCount.getValue());
}
if (theOffset != null) {
paramMap.setOffset(theOffset.getValue());
}
paramMap.setIncludes(Collections.singleton(IResource.INCLUDE_ALL.asRecursive()));
paramMap.setSort(theSort);
paramMap.setLastUpdated(theLastUpdate);
if (theId != null) {
paramMap.add("_id", new StringParam(theId.getIdPart()));
}
return search(paramMap, theRequestDetails);
}
}

View File

@ -1,83 +0,0 @@
package ca.uhn.fhir.jpa.dao.dstu3;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDaoObservation;
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.partition.IRequestPartitionHelperSvc;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.rest.api.CacheControlDirective;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
import org.hl7.fhir.dstu3.model.Observation;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.springframework.beans.factory.annotation.Autowired;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
public class FhirResourceDaoObservationDstu3 extends BaseHapiFhirResourceDaoObservation<Observation> {
@Autowired
private IRequestPartitionHelperSvc myPartitionHelperSvc;
@Override
public IBundleProvider observationsLastN(SearchParameterMap theSearchParameterMap, RequestDetails theRequestDetails, HttpServletResponse theServletResponse) {
updateSearchParamsForLastn(theSearchParameterMap, theRequestDetails);
RequestPartitionId requestPartitionId = myPartitionHelperSvc.determineReadPartitionForRequestForSearchType(theRequestDetails, getResourceName(), theSearchParameterMap, null);
return mySearchCoordinatorSvc.registerSearch(this, theSearchParameterMap, getResourceName(), new CacheControlDirective().parse(theRequestDetails.getHeaders(Constants.HEADER_CACHE_CONTROL)), theRequestDetails, requestPartitionId);
}
@Override
protected String getEffectiveParamName() {
return Observation.SP_DATE;
}
@Override
protected String getCodeParamName() {
return Observation.SP_CODE;
}
@Override
protected String getSubjectParamName() {
return Observation.SP_SUBJECT;
}
@Override
protected String getPatientParamName() {
return Observation.SP_PATIENT;
}
@Override
public ResourceTable updateEntity(RequestDetails theRequest, IBaseResource theResource, IBasePersistedResource theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing,
boolean theUpdateVersion, TransactionDetails theTransactionDetails, boolean theForceUpdate, boolean theCreateNewHistoryEntry) {
return updateObservationEntity(theRequest, theResource, theEntity, theDeletedTimestampOrNull,
thePerformIndexing, theUpdateVersion, theTransactionDetails, theForceUpdate,
theCreateNewHistoryEntry);
}
}

View File

@ -1,80 +0,0 @@
package ca.uhn.fhir.jpa.dao.dstu3;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoSearchParameter;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.dao.r4.FhirResourceDaoSearchParameterR4;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.searchparam.extractor.ISearchParamExtractor;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_30_40;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_40;
import org.hl7.fhir.dstu3.model.PrimitiveType;
import org.hl7.fhir.dstu3.model.SearchParameter;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
import java.util.stream.Collectors;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* 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 FhirResourceDaoSearchParameterDstu3 extends BaseHapiFhirResourceDao<SearchParameter> implements IFhirResourceDaoSearchParameter<SearchParameter> {
@Autowired
private ISearchParamExtractor mySearchParamExtractor;
protected void reindexAffectedResources(SearchParameter theResource, RequestDetails theRequestDetails) {
Boolean reindex = theResource != null ? CURRENTLY_REINDEXING.get(theResource) : null;
String expression = theResource != null ? theResource.getExpression() : null;
List<String> base = theResource != null ? theResource.getBase().stream().map(PrimitiveType::asStringValue).collect(Collectors.toList()) : null;
requestReindexForRelatedResources(reindex, base, theRequestDetails);
}
@Override
protected void postPersist(ResourceTable theEntity, SearchParameter theResource, RequestDetails theRequestDetails) {
super.postPersist(theEntity, theResource, theRequestDetails);
reindexAffectedResources(theResource, theRequestDetails);
}
@Override
protected void postUpdate(ResourceTable theEntity, SearchParameter theResource, RequestDetails theRequestDetails) {
super.postUpdate(theEntity, theResource, theRequestDetails);
reindexAffectedResources(theResource, theRequestDetails);
}
@Override
protected void preDelete(SearchParameter theResourceToDelete, ResourceTable theEntityToDelete, RequestDetails theRequestDetails) {
super.preDelete(theResourceToDelete, theEntityToDelete, theRequestDetails);
reindexAffectedResources(theResourceToDelete, theRequestDetails);
}
@Override
protected void validateResourceForStorage(SearchParameter theResource, ResourceTable theEntityToSave) {
super.validateResourceForStorage(theResource, theEntityToSave);
org.hl7.fhir.r4.model.SearchParameter resource = (org.hl7.fhir.r4.model.SearchParameter) VersionConvertorFactory_30_40.convertResource(theResource, new BaseAdvisor_30_40(false));
FhirResourceDaoSearchParameterR4.validateSearchParam(
resource,
getContext(), getConfig(), mySearchParamRegistry, mySearchParamExtractor);
}
}

View File

@ -1,88 +0,0 @@
package ca.uhn.fhir.jpa.dao.r4;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDaoObservation;
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.partition.IRequestPartitionHelperSvc;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.rest.api.CacheControlDirective;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.Observation;
import org.springframework.beans.factory.annotation.Autowired;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
public class FhirResourceDaoObservationR4 extends BaseHapiFhirResourceDaoObservation<Observation> {
@PersistenceContext(type = PersistenceContextType.TRANSACTION)
protected EntityManager myEntityManager;
@Autowired
private IRequestPartitionHelperSvc myRequestPartitionHelperService;
@Override
public IBundleProvider observationsLastN(SearchParameterMap theSearchParameterMap, RequestDetails theRequestDetails, HttpServletResponse theServletResponse) {
updateSearchParamsForLastn(theSearchParameterMap, theRequestDetails);
RequestPartitionId requestPartitionId = myRequestPartitionHelperService.determineReadPartitionForRequestForSearchType(theRequestDetails, getResourceName(), theSearchParameterMap, null);
return mySearchCoordinatorSvc.registerSearch(this, theSearchParameterMap, getResourceName(), new CacheControlDirective().parse(theRequestDetails.getHeaders(Constants.HEADER_CACHE_CONTROL)), theRequestDetails, requestPartitionId);
}
@Override
protected String getEffectiveParamName() {
return Observation.SP_DATE;
}
@Override
protected String getCodeParamName() {
return Observation.SP_CODE;
}
@Override
protected String getSubjectParamName() {
return Observation.SP_SUBJECT;
}
@Override
protected String getPatientParamName() {
return Observation.SP_PATIENT;
}
@Override
public ResourceTable updateEntity(RequestDetails theRequest, IBaseResource theResource, IBasePersistedResource theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing,
boolean theUpdateVersion, TransactionDetails theTransactionDetails, boolean theForceUpdate, boolean theCreateNewHistoryEntry) {
return updateObservationEntity(theRequest, theResource, theEntity, theDeletedTimestampOrNull,
thePerformIndexing, theUpdateVersion, theTransactionDetails, theForceUpdate,
theCreateNewHistoryEntry);
}
}

View File

@ -1,59 +0,0 @@
package ca.uhn.fhir.jpa.dao.r4b;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoComposition;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.param.StringParam;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.hl7.fhir.r4b.model.Composition;
import javax.servlet.http.HttpServletRequest;
import java.util.Collections;
public class FhirResourceDaoCompositionR4B extends BaseHapiFhirResourceDao<Composition> implements IFhirResourceDaoComposition<Composition> {
@Override
public IBundleProvider getDocumentForComposition(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdate, SortSpec theSort, RequestDetails theRequestDetails) {
SearchParameterMap paramMap = new SearchParameterMap();
if (theCount != null) {
paramMap.setCount(theCount.getValue());
}
if (theOffset != null) {
paramMap.setOffset(theOffset.getValue());
}
paramMap.setIncludes(Collections.singleton(IBaseResource.INCLUDE_ALL.asRecursive()));
paramMap.setSort(theSort);
paramMap.setLastUpdated(theLastUpdate);
if (theId != null) {
paramMap.add("_id", new StringParam(theId.getIdPart()));
}
return search(paramMap, theRequestDetails);
}
}

View File

@ -1,83 +0,0 @@
package ca.uhn.fhir.jpa.dao.r4b;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDaoObservation;
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.partition.IRequestPartitionHelperSvc;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.rest.api.CacheControlDirective;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4b.model.Observation;
import org.springframework.beans.factory.annotation.Autowired;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
public class FhirResourceDaoObservationR4B extends BaseHapiFhirResourceDaoObservation<Observation> {
@Autowired
private IRequestPartitionHelperSvc myPartitionHelperSvc;
@Override
public IBundleProvider observationsLastN(SearchParameterMap theSearchParameterMap, RequestDetails theRequestDetails, HttpServletResponse theServletResponse) {
updateSearchParamsForLastn(theSearchParameterMap, theRequestDetails);
RequestPartitionId requestPartitionId = myPartitionHelperSvc.determineReadPartitionForRequestForSearchType(theRequestDetails, getResourceName(), theSearchParameterMap, null);
return mySearchCoordinatorSvc.registerSearch(this, theSearchParameterMap, getResourceName(), new CacheControlDirective().parse(theRequestDetails.getHeaders(Constants.HEADER_CACHE_CONTROL)), theRequestDetails, requestPartitionId);
}
@Override
protected String getEffectiveParamName() {
return org.hl7.fhir.r4.model.Observation.SP_DATE;
}
@Override
protected String getCodeParamName() {
return org.hl7.fhir.r4.model.Observation.SP_CODE;
}
@Override
protected String getSubjectParamName() {
return org.hl7.fhir.r4.model.Observation.SP_SUBJECT;
}
@Override
protected String getPatientParamName() {
return org.hl7.fhir.r4.model.Observation.SP_PATIENT;
}
@Override
public ResourceTable updateEntity(RequestDetails theRequest, IBaseResource theResource, IBasePersistedResource theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing,
boolean theUpdateVersion, TransactionDetails theTransactionDetails, boolean theForceUpdate, boolean theCreateNewHistoryEntry) {
return updateObservationEntity(theRequest, theResource, theEntity, theDeletedTimestampOrNull,
thePerformIndexing, theUpdateVersion, theTransactionDetails, theForceUpdate,
theCreateNewHistoryEntry);
}
}

View File

@ -1,83 +0,0 @@
package ca.uhn.fhir.jpa.dao.r4b;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoSearchParameter;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.dao.r4.FhirResourceDaoSearchParameterR4;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.searchparam.extractor.ISearchParamExtractor;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_40_50;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_43_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_43_50;
import org.hl7.fhir.r4b.model.CodeType;
import org.hl7.fhir.r4b.model.SearchParameter;
import org.hl7.fhir.r5.model.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
import java.util.stream.Collectors;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* 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 FhirResourceDaoSearchParameterR4B extends BaseHapiFhirResourceDao<SearchParameter> implements IFhirResourceDaoSearchParameter<SearchParameter> {
@Autowired
private ISearchParamExtractor mySearchParamExtractor;
protected void refactorAffectedResources(SearchParameter theResource, RequestDetails theRequestDetails) {
Boolean reindex = theResource != null ? CURRENTLY_REINDEXING.get(theResource) : null;
String expression = theResource != null ? theResource.getExpression() : null;
List<String> base = theResource != null ? theResource.getBase().stream().map(CodeType::getCode).collect(Collectors.toList()) : null;
requestReindexForRelatedResources(reindex, base, theRequestDetails);
}
@Override
protected void postPersist(ResourceTable theEntity, SearchParameter theResource, RequestDetails theRequestDetails) {
super.postPersist(theEntity, theResource, theRequestDetails);
refactorAffectedResources(theResource, theRequestDetails);
}
@Override
protected void postUpdate(ResourceTable theEntity, SearchParameter theResource, RequestDetails theRequestDetails) {
super.postUpdate(theEntity, theResource, theRequestDetails);
refactorAffectedResources(theResource, theRequestDetails);
}
@Override
protected void preDelete(SearchParameter theResourceToDelete, ResourceTable theEntityToDelete, RequestDetails theRequestDetails) {
super.preDelete(theResourceToDelete, theEntityToDelete, theRequestDetails);
refactorAffectedResources(theResourceToDelete, theRequestDetails);
}
@Override
protected void validateResourceForStorage(SearchParameter theResource, ResourceTable theEntityToSave) {
super.validateResourceForStorage(theResource, theEntityToSave);
Resource resR5 = VersionConvertorFactory_43_50.convertResource(theResource, new BaseAdvisor_43_50(false));
FhirResourceDaoSearchParameterR4.validateSearchParam(
(org.hl7.fhir.r4.model.SearchParameter) VersionConvertorFactory_40_50.convertResource(resR5, new BaseAdvisor_40_50(false)),
getContext(), getConfig(), mySearchParamRegistry, mySearchParamExtractor);
}
}

View File

@ -1,59 +0,0 @@
package ca.uhn.fhir.jpa.dao.r5;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoComposition;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.param.StringParam;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.hl7.fhir.r5.model.Composition;
import javax.servlet.http.HttpServletRequest;
import java.util.Collections;
public class FhirResourceDaoCompositionR5 extends BaseHapiFhirResourceDao<Composition> implements IFhirResourceDaoComposition<Composition> {
@Override
public IBundleProvider getDocumentForComposition(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdate, SortSpec theSort, RequestDetails theRequestDetails) {
SearchParameterMap paramMap = new SearchParameterMap();
if (theCount != null) {
paramMap.setCount(theCount.getValue());
}
if (theOffset != null) {
paramMap.setOffset(theOffset.getValue());
}
paramMap.setIncludes(Collections.singleton(IBaseResource.INCLUDE_ALL.asRecursive()));
paramMap.setSort(theSort);
paramMap.setLastUpdated(theLastUpdate);
if (theId != null) {
paramMap.add("_id", new StringParam(theId.getIdPart()));
}
return search(paramMap, theRequestDetails);
}
}

View File

@ -1,83 +0,0 @@
package ca.uhn.fhir.jpa.dao.r5;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDaoObservation;
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.partition.IRequestPartitionHelperSvc;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.rest.api.CacheControlDirective;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r5.model.Observation;
import org.springframework.beans.factory.annotation.Autowired;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
public class FhirResourceDaoObservationR5 extends BaseHapiFhirResourceDaoObservation<Observation> {
@Autowired
private IRequestPartitionHelperSvc myPartitionHelperSvc;
@Override
public IBundleProvider observationsLastN(SearchParameterMap theSearchParameterMap, RequestDetails theRequestDetails, HttpServletResponse theServletResponse) {
updateSearchParamsForLastn(theSearchParameterMap, theRequestDetails);
RequestPartitionId requestPartitionId = myPartitionHelperSvc.determineReadPartitionForRequestForSearchType(theRequestDetails, getResourceName(), theSearchParameterMap, null);
return mySearchCoordinatorSvc.registerSearch(this, theSearchParameterMap, getResourceName(), new CacheControlDirective().parse(theRequestDetails.getHeaders(Constants.HEADER_CACHE_CONTROL)), theRequestDetails, requestPartitionId);
}
@Override
protected String getEffectiveParamName() {
return org.hl7.fhir.r4.model.Observation.SP_DATE;
}
@Override
protected String getCodeParamName() {
return org.hl7.fhir.r4.model.Observation.SP_CODE;
}
@Override
protected String getSubjectParamName() {
return org.hl7.fhir.r4.model.Observation.SP_SUBJECT;
}
@Override
protected String getPatientParamName() {
return org.hl7.fhir.r4.model.Observation.SP_PATIENT;
}
@Override
public ResourceTable updateEntity(RequestDetails theRequest, IBaseResource theResource, IBasePersistedResource theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing,
boolean theUpdateVersion, TransactionDetails theTransactionDetails, boolean theForceUpdate, boolean theCreateNewHistoryEntry) {
return updateObservationEntity(theRequest, theResource, theEntity, theDeletedTimestampOrNull,
thePerformIndexing, theUpdateVersion, theTransactionDetails, theForceUpdate,
theCreateNewHistoryEntry);
}
}

View File

@ -1,79 +0,0 @@
package ca.uhn.fhir.jpa.dao.r5;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoSearchParameter;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.dao.r4.FhirResourceDaoSearchParameterR4;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.searchparam.extractor.ISearchParamExtractor;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_40_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50;
import org.hl7.fhir.r5.model.CodeType;
import org.hl7.fhir.r5.model.SearchParameter;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
import java.util.stream.Collectors;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* 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 FhirResourceDaoSearchParameterR5 extends BaseHapiFhirResourceDao<SearchParameter> implements IFhirResourceDaoSearchParameter<SearchParameter> {
@Autowired
private ISearchParamExtractor mySearchParamExtractor;
protected void refactorAffectedResources(SearchParameter theResource, RequestDetails theRequestDetails) {
Boolean reindex = theResource != null ? CURRENTLY_REINDEXING.get(theResource) : null;
String expression = theResource != null ? theResource.getExpression() : null;
List<String> base = theResource != null ? theResource.getBase().stream().map(CodeType::getCode).collect(Collectors.toList()) : null;
requestReindexForRelatedResources(reindex, base, theRequestDetails);
}
@Override
protected void postPersist(ResourceTable theEntity, SearchParameter theResource, RequestDetails theRequestDetails) {
super.postPersist(theEntity, theResource, theRequestDetails);
refactorAffectedResources(theResource, theRequestDetails);
}
@Override
protected void postUpdate(ResourceTable theEntity, SearchParameter theResource, RequestDetails theRequestDetails) {
super.postUpdate(theEntity, theResource, theRequestDetails);
refactorAffectedResources(theResource, theRequestDetails);
}
@Override
protected void preDelete(SearchParameter theResourceToDelete, ResourceTable theEntityToDelete, RequestDetails theRequestDetails) {
super.preDelete(theResourceToDelete, theEntityToDelete, theRequestDetails);
refactorAffectedResources(theResourceToDelete, theRequestDetails);
}
@Override
protected void validateResourceForStorage(SearchParameter theResource, ResourceTable theEntityToSave) {
super.validateResourceForStorage(theResource, theEntityToSave);
FhirResourceDaoSearchParameterR4.validateSearchParam(
(org.hl7.fhir.r4.model.SearchParameter) VersionConvertorFactory_40_50.convertResource(theResource, new BaseAdvisor_40_50(false)),
getContext(), getConfig(), mySearchParamRegistry, mySearchParamExtractor);
}
}

View File

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -44,12 +44,6 @@ public class BaseCqlR4Test extends BaseJpaR4Test implements CqlProviderTestBase
@RegisterExtension @RegisterExtension
protected PartitionHelper myPartitionHelper; protected PartitionHelper myPartitionHelper;
// FIXME: restore?
// @Override
// public void beforeResetInterceptors() {
// myInterceptorRegistry.unregisterInterceptorsIf(t->!(t instanceof PartitionHelper.MyTestInterceptor));
// }
@Autowired @Autowired
protected protected
DaoRegistry myDaoRegistry; DaoRegistry myDaoRegistry;

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -179,33 +179,35 @@ public class SearchParameterCanonicalizer {
String path = theNextSp.getExpression(); String path = theNextSp.getExpression();
RestSearchParameterTypeEnum paramType = null; RestSearchParameterTypeEnum paramType = null;
RuntimeSearchParam.RuntimeSearchParamStatusEnum status = null; RuntimeSearchParam.RuntimeSearchParamStatusEnum status = null;
switch (theNextSp.getType()) { if (theNextSp.getType() != null) {
case COMPOSITE: switch (theNextSp.getType()) {
paramType = RestSearchParameterTypeEnum.COMPOSITE; case COMPOSITE:
break; paramType = RestSearchParameterTypeEnum.COMPOSITE;
case DATE: break;
paramType = RestSearchParameterTypeEnum.DATE; case DATE:
break; paramType = RestSearchParameterTypeEnum.DATE;
case NUMBER: break;
paramType = RestSearchParameterTypeEnum.NUMBER; case NUMBER:
break; paramType = RestSearchParameterTypeEnum.NUMBER;
case QUANTITY: break;
paramType = RestSearchParameterTypeEnum.QUANTITY; case QUANTITY:
break; paramType = RestSearchParameterTypeEnum.QUANTITY;
case REFERENCE: break;
paramType = RestSearchParameterTypeEnum.REFERENCE; case REFERENCE:
break; paramType = RestSearchParameterTypeEnum.REFERENCE;
case STRING: break;
paramType = RestSearchParameterTypeEnum.STRING; case STRING:
break; paramType = RestSearchParameterTypeEnum.STRING;
case TOKEN: break;
paramType = RestSearchParameterTypeEnum.TOKEN; case TOKEN:
break; paramType = RestSearchParameterTypeEnum.TOKEN;
case URI: break;
paramType = RestSearchParameterTypeEnum.URI; case URI:
break; paramType = RestSearchParameterTypeEnum.URI;
case NULL: break;
break; case NULL:
break;
}
} }
if (theNextSp.getStatus() != null) { if (theNextSp.getStatus() != null) {
switch (theNextSp.getStatus()) { switch (theNextSp.getStatus()) {

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -39,6 +39,7 @@ import ca.uhn.fhir.jpa.subscription.model.CanonicalSubscriptionChannelType;
import ca.uhn.fhir.parser.DataFormatException; import ca.uhn.fhir.parser.DataFormatException;
import ca.uhn.fhir.rest.api.EncodingEnum; import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException; import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.fhir.util.HapiExtensions; import ca.uhn.fhir.util.HapiExtensions;
@ -94,7 +95,12 @@ public class SubscriptionValidatingInterceptor {
return; return;
} }
CanonicalSubscription subscription = mySubscriptionCanonicalizer.canonicalize(theSubscription); CanonicalSubscription subscription;
try {
subscription = mySubscriptionCanonicalizer.canonicalize(theSubscription);
} catch (InternalErrorException e) {
throw new UnprocessableEntityException(Msg.code(955) + e.getMessage());
}
boolean finished = false; boolean finished = false;
if (subscription.getStatus() == null) { if (subscription.getStatus() == null) {
throw new UnprocessableEntityException(Msg.code(8) + "Can not process submitted Subscription - Subscription.status must be populated on this server"); throw new UnprocessableEntityException(Msg.code(8) + "Can not process submitted Subscription - Subscription.status must be populated on this server");

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -22,6 +22,7 @@ import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistryController;
import ca.uhn.fhir.jpa.sp.ISearchParamPresenceSvc; import ca.uhn.fhir.jpa.sp.ISearchParamPresenceSvc;
import ca.uhn.fhir.jpa.subscription.match.registry.SubscriptionLoader; import ca.uhn.fhir.jpa.subscription.match.registry.SubscriptionLoader;
import ca.uhn.fhir.jpa.test.BaseJpaTest; import ca.uhn.fhir.jpa.test.BaseJpaTest;
import ca.uhn.fhir.jpa.test.PreventDanglingInterceptorsExtension;
import ca.uhn.fhir.jpa.test.config.TestDstu2Config; import ca.uhn.fhir.jpa.test.config.TestDstu2Config;
import ca.uhn.fhir.jpa.util.ResourceCountCache; import ca.uhn.fhir.jpa.util.ResourceCountCache;
import ca.uhn.fhir.model.dstu2.composite.MetaDt; import ca.uhn.fhir.model.dstu2.composite.MetaDt;
@ -60,6 +61,7 @@ import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
@ -213,6 +215,9 @@ public abstract class BaseJpaDstu2Test extends BaseJpaTest {
@Autowired @Autowired
private ValidationSupportChain myJpaValidationSupportChain; private ValidationSupportChain myJpaValidationSupportChain;
@RegisterExtension
private final PreventDanglingInterceptorsExtension myPreventDanglingInterceptorsExtension = new PreventDanglingInterceptorsExtension(()-> myInterceptorRegistry);
@BeforeEach @BeforeEach
public void beforeFlushFT() { public void beforeFlushFT() {
purgeHibernateSearch(myEntityManager); purgeHibernateSearch(myEntityManager);
@ -232,13 +237,6 @@ public abstract class BaseJpaDstu2Test extends BaseJpaTest {
myDaoConfig.setAllowExternalReferences(new DaoConfig().isAllowExternalReferences()); myDaoConfig.setAllowExternalReferences(new DaoConfig().isAllowExternalReferences());
} }
@Override
@AfterEach
public void afterResetInterceptors() {
super.afterResetInterceptors();
myInterceptorRegistry.unregisterAllInterceptors();
}
@Override @Override
public FhirContext getFhirContext() { public FhirContext getFhirContext() {
return myFhirContext; return myFhirContext;

View File

@ -58,6 +58,7 @@ public class SubscriptionsDstu2Test extends BaseResourceProviderDstu2Test {
Subscription subs = new Subscription(); Subscription subs = new Subscription();
subs.getChannel().setType(SubscriptionChannelTypeEnum.REST_HOOK); subs.getChannel().setType(SubscriptionChannelTypeEnum.REST_HOOK);
subs.setCriteria("Observation?identifier=123"); subs.setCriteria("Observation?identifier=123");
subs.getChannel().setEndpoint("http://localhost");
try { try {
myClient.create().resource(subs).execute(); myClient.create().resource(subs).execute();
fail(); fail();
@ -105,6 +106,7 @@ public class SubscriptionsDstu2Test extends BaseResourceProviderDstu2Test {
public void testCreateWithPopulatedButInvalidStatue() { public void testCreateWithPopulatedButInvalidStatue() {
Subscription subs = new Subscription(); Subscription subs = new Subscription();
subs.getChannel().setType(SubscriptionChannelTypeEnum.WEBSOCKET); subs.getChannel().setType(SubscriptionChannelTypeEnum.WEBSOCKET);
subs.getChannel().setEndpoint("http://localhost");
subs.setCriteria("Observation?identifier=123"); subs.setCriteria("Observation?identifier=123");
subs.getStatusElement().setValue("aaaaa"); subs.getStatusElement().setValue("aaaaa");
@ -112,7 +114,7 @@ public class SubscriptionsDstu2Test extends BaseResourceProviderDstu2Test {
myClient.create().resource(subs).execute(); myClient.create().resource(subs).execute();
fail(); fail();
} catch (UnprocessableEntityException e) { } catch (UnprocessableEntityException e) {
assertThat(e.getMessage(), containsString("Subscription.status must be populated on this server")); assertThat(e.getMessage(), containsString("Unknown SubscriptionStatus code 'aaaaa'"));
} }
} }
@ -152,6 +154,7 @@ public class SubscriptionsDstu2Test extends BaseResourceProviderDstu2Test {
Subscription subs = new Subscription(); Subscription subs = new Subscription();
subs.getChannel().setType(SubscriptionChannelTypeEnum.REST_HOOK); subs.getChannel().setType(SubscriptionChannelTypeEnum.REST_HOOK);
subs.setCriteria("Observation?identifier=123"); subs.setCriteria("Observation?identifier=123");
subs.getChannel().setEndpoint("http://localhost");
subs.setStatus(SubscriptionStatusEnum.REQUESTED); subs.setStatus(SubscriptionStatusEnum.REQUESTED);
IIdType id = myClient.create().resource(subs).execute().getId(); IIdType id = myClient.create().resource(subs).execute().getId();
subs.setId(id); subs.setId(id);

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -93,7 +93,7 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu
} }
@Test @Test
public void testCreateSpWithMultiplePaths(){ public void testCreateSpWithMultiplePaths() {
SearchParameter sp = new SearchParameter(); SearchParameter sp = new SearchParameter();
sp.setCode("telephone-unformatted"); sp.setCode("telephone-unformatted");
sp.setStatus(Enumerations.PublicationStatus.ACTIVE); sp.setStatus(Enumerations.PublicationStatus.ACTIVE);
@ -101,18 +101,56 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu
sp.getBase().add(new CodeType("Patient")); sp.getBase().add(new CodeType("Patient"));
sp.setType(Enumerations.SearchParamType.TOKEN); sp.setType(Enumerations.SearchParamType.TOKEN);
DaoMethodOutcome daoMethodOutcome = mySearchParameterDao.create(sp); DaoMethodOutcome daoMethodOutcome;
daoMethodOutcome = mySearchParameterDao.create(sp);
assertThat(daoMethodOutcome.getId(), is(notNullValue())); assertThat(daoMethodOutcome.getId(), is(notNullValue()));
}
@Test
public void testCreateSpWithMultiplePaths2() {
SearchParameter sp = new SearchParameter();
sp.setCode("telephone-unformatted");
sp.setStatus(Enumerations.PublicationStatus.ACTIVE);
sp.setExpression("Patient.telecom.where(system='phone' or system='email')");
sp.getBase().add(new CodeType("Patient"));
sp.setType(Enumerations.SearchParamType.TOKEN);
DaoMethodOutcome daoMethodOutcome;
sp.setExpression("Patient.telecom.where(system='phone') or Patient.telecome.where(system='email')"); sp.setExpression("Patient.telecom.where(system='phone') or Patient.telecome.where(system='email')");
sp.setCode("telephone-unformatted-2"); sp.setCode("telephone-unformatted-2");
daoMethodOutcome = mySearchParameterDao.create(sp); daoMethodOutcome = mySearchParameterDao.create(sp);
assertThat(daoMethodOutcome.getId(), is(notNullValue())); assertThat(daoMethodOutcome.getId(), is(notNullValue()));
}
@Test
public void testCreateSpWithMultiplePaths3() {
SearchParameter sp = new SearchParameter();
sp.setCode("telephone-unformatted");
sp.setStatus(Enumerations.PublicationStatus.ACTIVE);
sp.setExpression("Patient.telecom.where(system='phone' or system='email')");
sp.getBase().add(new CodeType("Patient"));
sp.setType(Enumerations.SearchParamType.TOKEN);
DaoMethodOutcome daoMethodOutcome;
sp.setExpression("Patient.telecom.where(system='phone' or system='email') | Patient.telecome.where(system='email')"); sp.setExpression("Patient.telecom.where(system='phone' or system='email') | Patient.telecome.where(system='email')");
sp.setCode("telephone-unformatted-3"); sp.setCode("telephone-unformatted-3");
daoMethodOutcome = mySearchParameterDao.create(sp); daoMethodOutcome = mySearchParameterDao.create(sp);
assertThat(daoMethodOutcome.getId(), is(notNullValue())); assertThat(daoMethodOutcome.getId(), is(notNullValue()));
}
@Test
public void testCreateSpWithMultiplePaths4() {
SearchParameter sp = new SearchParameter();
sp.setCode("telephone-unformatted");
sp.setStatus(Enumerations.PublicationStatus.ACTIVE);
sp.setExpression("Patient.telecom.where(system='phone' or system='email')");
sp.getBase().add(new CodeType("Patient"));
sp.setType(Enumerations.SearchParamType.TOKEN);
DaoMethodOutcome daoMethodOutcome;
sp.setExpression("Patient.telecom.where(system='phone' or system='email') | Patient.telecom.where(system='email') or Patient.telecom.where(system='mail' | system='phone')"); sp.setExpression("Patient.telecom.where(system='phone' or system='email') | Patient.telecom.where(system='email') or Patient.telecom.where(system='mail' | system='phone')");
sp.setCode("telephone-unformatted-3"); sp.setCode("telephone-unformatted-3");
@ -120,7 +158,6 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu
assertThat(daoMethodOutcome.getId(), is(notNullValue())); assertThat(daoMethodOutcome.getId(), is(notNullValue()));
} }
@Test @Test
public void testCreateInvalidParamNoPath() { public void testCreateInvalidParamNoPath() {
SearchParameter fooSp = new SearchParameter(); SearchParameter fooSp = new SearchParameter();
@ -1110,21 +1147,21 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu
medAdmin.setMedication(new Reference(medication)); medAdmin.setMedication(new Reference(medication));
myMedicationAdministrationDao.create(medAdmin); myMedicationAdministrationDao.create(medAdmin);
runInTransaction(()->{ runInTransaction(() -> {
List<ResourceIndexedSearchParamToken> tokens = myResourceIndexedSearchParamTokenDao List<ResourceIndexedSearchParamToken> tokens = myResourceIndexedSearchParamTokenDao
.findAll() .findAll()
.stream() .stream()
.filter(t -> t.getParamName().equals("medicationadministration-ingredient-medication")) .filter(t -> t.getParamName().equals("medicationadministration-ingredient-medication"))
.collect(Collectors.toList()); .collect(Collectors.toList());
ourLog.info("Tokens:\n * {}", tokens.stream().map(t->t.toString()).collect(Collectors.joining("\n * "))); ourLog.info("Tokens:\n * {}", tokens.stream().map(t -> t.toString()).collect(Collectors.joining("\n * ")));
assertEquals(1, tokens.size(), tokens.toString()); assertEquals(1, tokens.size(), tokens.toString());
assertEquals(false, tokens.get(0).isMissing()); assertEquals(false, tokens.get(0).isMissing());
}); });
SearchParameterMap map = SearchParameterMap.newSynchronous(); SearchParameterMap map = SearchParameterMap.newSynchronous();
map.add("medicationadministration-ingredient-medication", new TokenParam("system","code")); map.add("medicationadministration-ingredient-medication", new TokenParam("system", "code"));
myCaptureQueriesListener.clear(); myCaptureQueriesListener.clear();
IBundleProvider search = myMedicationAdministrationDao.search(map); IBundleProvider search = myMedicationAdministrationDao.search(map);
myCaptureQueriesListener.logSelectQueriesForCurrentThread(); myCaptureQueriesListener.logSelectQueriesForCurrentThread();
@ -1133,5 +1170,4 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu
} }
} }

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -404,18 +404,6 @@ public class Batch2CoordinatorIT extends BaseJpaR4Test {
@Test @Test
public void testStepRunFailure_continuouslyThrows_marksJobFailed() { public void testStepRunFailure_continuouslyThrows_marksJobFailed() {
// FIXME: remove
// AtomicInteger interceptorCounter = new AtomicInteger();
// myWorkChannel.addInterceptor(new ExecutorChannelInterceptor() {
// @Override
// public void afterMessageHandled(Message<?> message, MessageChannel channel, MessageHandler handler, Exception ex) {
// if (ex != null) {
// interceptorCounter.incrementAndGet();
// ourLog.info("Work Channel Exception thrown: {}. Resending message", ex.getMessage());
// channel.send(message);
// }
// }
// });
// setup // setup
AtomicInteger counter = new AtomicInteger(); AtomicInteger counter = new AtomicInteger();

View File

@ -1,4 +1,4 @@
package ca.uhn.fhir.jpa.dao.r4; package ca.uhn.fhir.jpa.dao;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.context.RuntimeResourceDefinition;
@ -6,6 +6,7 @@ import ca.uhn.fhir.context.RuntimeSearchParam;
import ca.uhn.fhir.i18n.Msg; import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.api.config.DaoConfig; import ca.uhn.fhir.jpa.api.config.DaoConfig;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException; import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.hapi.converters.canonical.VersionCanonicalizer;
import org.hl7.fhir.r4.model.Enumerations; import org.hl7.fhir.r4.model.Enumerations;
import org.hl7.fhir.r4.model.SearchParameter; import org.hl7.fhir.r4.model.SearchParameter;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
@ -22,11 +23,11 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assertions.fail;
@ExtendWith(MockitoExtension.class) @ExtendWith(MockitoExtension.class)
public class FhirResourceDaoSearchParameterR4Test { public class JpaResourceDaoSearchParameterTest {
private static final Logger ourLog = LoggerFactory.getLogger(FhirResourceDaoSearchParameterR4Test.class); private static final Logger ourLog = LoggerFactory.getLogger(JpaResourceDaoSearchParameterTest.class);
private FhirContext myCtx; private FhirContext myCtx;
private FhirResourceDaoSearchParameterR4 myDao; private JpaResourceDaoSearchParameter<SearchParameter> myDao;
@Mock @Mock
private ApplicationContext myApplicationContext; private ApplicationContext myApplicationContext;
@ -34,10 +35,13 @@ public class FhirResourceDaoSearchParameterR4Test {
public void before() { public void before() {
myCtx = FhirContext.forR4Cached(); myCtx = FhirContext.forR4Cached();
myDao = new FhirResourceDaoSearchParameterR4(); VersionCanonicalizer versionCanonicalizer = new VersionCanonicalizer(myCtx);
myDao = new JpaResourceDaoSearchParameter<>();
myDao.setContext(myCtx); myDao.setContext(myCtx);
myDao.setDaoConfigForUnitTest(new DaoConfig()); myDao.setDaoConfigForUnitTest(new DaoConfig());
myDao.setApplicationContext(myApplicationContext); myDao.setApplicationContext(myApplicationContext);
myDao.setVersionCanonicalizerForUnitTest(versionCanonicalizer);
myDao.start(); myDao.start();
} }
@ -58,7 +62,7 @@ public class FhirResourceDaoSearchParameterR4Test {
nextSearchParameter.setExpression(nextp.getPath()); nextSearchParameter.setExpression(nextp.getPath());
nextSearchParameter.setStatus(Enumerations.PublicationStatus.ACTIVE); nextSearchParameter.setStatus(Enumerations.PublicationStatus.ACTIVE);
nextSearchParameter.setType(Enumerations.SearchParamType.fromCode(nextp.getParamType().getCode())); nextSearchParameter.setType(Enumerations.SearchParamType.fromCode(nextp.getParamType().getCode()));
nextp.getBase().forEach(t -> nextSearchParameter.addBase(t)); nextp.getBase().forEach(nextSearchParameter::addBase);
ourLog.info("Validating {}.{}", nextResource, nextp.getName()); ourLog.info("Validating {}.{}", nextResource, nextp.getName());
myDao.validateResourceForStorage(nextSearchParameter, null); myDao.validateResourceForStorage(nextSearchParameter, null);

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -54,6 +54,7 @@ import ca.uhn.fhir.jpa.subscription.match.registry.SubscriptionRegistry;
import ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc; import ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc;
import ca.uhn.fhir.jpa.term.api.ITermDeferredStorageSvc; import ca.uhn.fhir.jpa.term.api.ITermDeferredStorageSvc;
import ca.uhn.fhir.jpa.test.BaseJpaTest; import ca.uhn.fhir.jpa.test.BaseJpaTest;
import ca.uhn.fhir.jpa.test.PreventDanglingInterceptorsExtension;
import ca.uhn.fhir.jpa.test.config.TestR4BConfig; import ca.uhn.fhir.jpa.test.config.TestR4BConfig;
import ca.uhn.fhir.jpa.util.ResourceCountCache; import ca.uhn.fhir.jpa.util.ResourceCountCache;
import ca.uhn.fhir.parser.IParser; import ca.uhn.fhir.parser.IParser;
@ -117,6 +118,7 @@ import org.hl7.fhir.r5.utils.validation.constants.BestPracticeWarningLevel;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
@ -382,6 +384,7 @@ public abstract class BaseJpaR4BTest extends BaseJpaTest implements ITestDataBui
@Autowired @Autowired
private IBulkDataExportJobSchedulingHelper myBulkDataSchedulerHelper; private IBulkDataExportJobSchedulingHelper myBulkDataSchedulerHelper;
@Override @Override
public IIdType doCreateResource(IBaseResource theResource) { public IIdType doCreateResource(IBaseResource theResource) {
IFhirResourceDao dao = myDaoRegistry.getResourceDao(theResource.getClass()); IFhirResourceDao dao = myDaoRegistry.getResourceDao(theResource.getClass());
@ -412,9 +415,11 @@ public abstract class BaseJpaR4BTest extends BaseJpaTest implements ITestDataBui
myPagingProvider.setMaximumPageSize(BasePagingProvider.DEFAULT_MAX_PAGE_SIZE); myPagingProvider.setMaximumPageSize(BasePagingProvider.DEFAULT_MAX_PAGE_SIZE);
} }
@Override
@AfterEach @AfterEach
public void afterResetInterceptors() { public void afterResetInterceptors() {
myInterceptorRegistry.unregisterAllInterceptors(); super.afterResetInterceptors();
myInterceptorRegistry.unregisterInterceptor(myPerformanceTracingLoggingInterceptor);
} }
@AfterEach() @AfterEach()

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -60,20 +60,14 @@ import ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc;
import ca.uhn.fhir.jpa.term.api.ITermDeferredStorageSvc; import ca.uhn.fhir.jpa.term.api.ITermDeferredStorageSvc;
import ca.uhn.fhir.jpa.term.api.ITermReadSvc; import ca.uhn.fhir.jpa.term.api.ITermReadSvc;
import ca.uhn.fhir.jpa.test.BaseJpaTest; import ca.uhn.fhir.jpa.test.BaseJpaTest;
import ca.uhn.fhir.jpa.test.PreventDanglingInterceptorsExtension;
import ca.uhn.fhir.jpa.test.config.TestR5Config; import ca.uhn.fhir.jpa.test.config.TestR5Config;
import ca.uhn.fhir.jpa.util.ResourceCountCache; import ca.uhn.fhir.jpa.util.ResourceCountCache;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.parser.StrictErrorHandler; import ca.uhn.fhir.parser.StrictErrorHandler;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.rest.server.BasePagingProvider; import ca.uhn.fhir.rest.server.BasePagingProvider;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor; import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
import ca.uhn.fhir.rest.server.provider.ResourceProviderFactory; import ca.uhn.fhir.rest.server.provider.ResourceProviderFactory;
import ca.uhn.fhir.test.utilities.ITestDataBuilder; import ca.uhn.fhir.test.utilities.ITestDataBuilder;
import ca.uhn.fhir.util.UrlUtil;
import ca.uhn.fhir.validation.FhirValidator;
import ca.uhn.fhir.validation.ValidationResult;
import org.hl7.fhir.common.hapi.validation.validator.FhirInstanceValidator;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r5.model.AllergyIntolerance; import org.hl7.fhir.r5.model.AllergyIntolerance;
@ -89,16 +83,12 @@ import org.hl7.fhir.r5.model.Communication;
import org.hl7.fhir.r5.model.CommunicationRequest; import org.hl7.fhir.r5.model.CommunicationRequest;
import org.hl7.fhir.r5.model.CompartmentDefinition; import org.hl7.fhir.r5.model.CompartmentDefinition;
import org.hl7.fhir.r5.model.ConceptMap; import org.hl7.fhir.r5.model.ConceptMap;
import org.hl7.fhir.r5.model.ConceptMap.ConceptMapGroupComponent;
import org.hl7.fhir.r5.model.ConceptMap.SourceElementComponent;
import org.hl7.fhir.r5.model.ConceptMap.TargetElementComponent;
import org.hl7.fhir.r5.model.Condition; import org.hl7.fhir.r5.model.Condition;
import org.hl7.fhir.r5.model.Consent; import org.hl7.fhir.r5.model.Consent;
import org.hl7.fhir.r5.model.Coverage; import org.hl7.fhir.r5.model.Coverage;
import org.hl7.fhir.r5.model.Device; import org.hl7.fhir.r5.model.Device;
import org.hl7.fhir.r5.model.DiagnosticReport; import org.hl7.fhir.r5.model.DiagnosticReport;
import org.hl7.fhir.r5.model.Encounter; import org.hl7.fhir.r5.model.Encounter;
import org.hl7.fhir.r5.model.Enumerations;
import org.hl7.fhir.r5.model.Group; import org.hl7.fhir.r5.model.Group;
import org.hl7.fhir.r5.model.Immunization; import org.hl7.fhir.r5.model.Immunization;
import org.hl7.fhir.r5.model.ImmunizationRecommendation; import org.hl7.fhir.r5.model.ImmunizationRecommendation;
@ -126,12 +116,11 @@ import org.hl7.fhir.r5.model.StructureDefinition;
import org.hl7.fhir.r5.model.Subscription; import org.hl7.fhir.r5.model.Subscription;
import org.hl7.fhir.r5.model.Substance; import org.hl7.fhir.r5.model.Substance;
import org.hl7.fhir.r5.model.Task; import org.hl7.fhir.r5.model.Task;
import org.hl7.fhir.r5.model.UriType;
import org.hl7.fhir.r5.model.ValueSet; import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.utils.validation.constants.BestPracticeWarningLevel;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
@ -142,22 +131,16 @@ import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
@ExtendWith(SpringExtension.class) @ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {TestR5Config.class}) @ContextConfiguration(classes = {TestR5Config.class})
public abstract class BaseJpaR5Test extends BaseJpaTest implements ITestDataBuilder { public abstract class BaseJpaR5Test extends BaseJpaTest implements ITestDataBuilder {
private static IValidationSupport ourJpaValidationSupportChainR5;
private static IFhirResourceDaoValueSet<ValueSet> ourValueSetDao;
@Autowired @Autowired
protected ITermCodeSystemStorageSvc myTermCodeSystemStorageSvc; protected ITermCodeSystemStorageSvc myTermCodeSystemStorageSvc;
@Autowired @Autowired
@ -401,8 +384,10 @@ public abstract class BaseJpaR5Test extends BaseJpaTest implements ITestDataBuil
protected ITermDeferredStorageSvc myTermDeferredStorageSvc; protected ITermDeferredStorageSvc myTermDeferredStorageSvc;
@Autowired @Autowired
private IValidationSupport myJpaValidationSupportChain; private IValidationSupport myJpaValidationSupportChain;
@RegisterExtension
private PreventDanglingInterceptorsExtension myPreventDanglingInterceptorsExtension = new PreventDanglingInterceptorsExtension(() -> myInterceptorRegistry);
private PerformanceTracingLoggingInterceptor myPerformanceTracingLoggingInterceptor; private PerformanceTracingLoggingInterceptor myPerformanceTracingLoggingInterceptor;
private List<Object> mySystemInterceptors;
@Autowired @Autowired
private DaoRegistry myDaoRegistry; private DaoRegistry myDaoRegistry;
@Autowired @Autowired
@ -438,13 +423,6 @@ public abstract class BaseJpaR5Test extends BaseJpaTest implements ITestDataBuil
myPagingProvider.setMaximumPageSize(BasePagingProvider.DEFAULT_MAX_PAGE_SIZE); myPagingProvider.setMaximumPageSize(BasePagingProvider.DEFAULT_MAX_PAGE_SIZE);
} }
@Override
@AfterEach
public void afterResetInterceptors() {
super.afterResetInterceptors();
myInterceptorRegistry.unregisterAllInterceptors();
}
@AfterEach @AfterEach
public void afterClearTerminologyCaches() { public void afterClearTerminologyCaches() {
TermReadSvcImpl baseHapiTerminologySvc = AopTestUtils.getTargetObject(myTermSvc); TermReadSvcImpl baseHapiTerminologySvc = AopTestUtils.getTargetObject(myTermSvc);
@ -455,16 +433,15 @@ public abstract class BaseJpaR5Test extends BaseJpaTest implements ITestDataBuil
deferredStorageSvc.clearDeferred(); deferredStorageSvc.clearDeferred();
} }
@AfterEach() @AfterEach
public void afterGrabCaches() { @Override
ourValueSetDao = myValueSetDao; protected void afterResetInterceptors() {
ourJpaValidationSupportChainR5 = myJpaValidationSupportChain; super.afterResetInterceptors();
myInterceptorRegistry.unregisterInterceptor(myPerformanceTracingLoggingInterceptor);
} }
@BeforeEach @BeforeEach
public void beforeCreateInterceptor() { public void beforeCreateInterceptor() {
mySystemInterceptors = myInterceptorRegistry.getAllRegisteredInterceptors();
myInterceptor = mock(IServerInterceptor.class); myInterceptor = mock(IServerInterceptor.class);
myPerformanceTracingLoggingInterceptor = new PerformanceTracingLoggingInterceptor(); myPerformanceTracingLoggingInterceptor = new PerformanceTracingLoggingInterceptor();
@ -495,60 +472,13 @@ public abstract class BaseJpaR5Test extends BaseJpaTest implements ITestDataBuil
return myTxManager; return myTxManager;
} }
protected void validate(IBaseResource theResource) {
FhirValidator validatorModule = myFhirCtx.newValidator();
FhirInstanceValidator instanceValidator = new FhirInstanceValidator(myValidationSupport);
instanceValidator.setBestPracticeWarningLevel(BestPracticeWarningLevel.Ignore);
validatorModule.registerValidatorModule(instanceValidator);
ValidationResult result = validatorModule.validateWithResult(theResource);
if (!result.isSuccessful()) {
fail(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(result.toOperationOutcome()));
}
}
@SuppressWarnings("unchecked")
protected void upload(String theClasspath) throws IOException {
String resource = loadResource(theClasspath);
IParser parser = EncodingEnum.detectEncoding(resource).newParser(myFhirCtx);
IBaseResource resourceParsed = parser.parseResource(resource);
IFhirResourceDao dao = myDaoRegistry.getResourceDao(resourceParsed.getIdElement().getResourceType());
dao.update(resourceParsed);
}
protected ValueSet.ValueSetExpansionContainsComponent assertExpandedValueSetContainsConcept(ValueSet theValueSet, String theSystem, String theCode, String theDisplay, Integer theDesignationCount) {
List<ValueSet.ValueSetExpansionContainsComponent> contains = theValueSet.getExpansion().getContains();
Stream<ValueSet.ValueSetExpansionContainsComponent> stream = contains.stream();
if (theSystem != null) {
stream = stream.filter(concept -> theSystem.equalsIgnoreCase(concept.getSystem()));
}
if (theCode != null) {
stream = stream.filter(concept -> theCode.equalsIgnoreCase(concept.getCode()));
}
if (theDisplay != null) {
stream = stream.filter(concept -> theDisplay.equalsIgnoreCase(concept.getDisplay()));
}
if (theDesignationCount != null) {
stream = stream.filter(concept -> concept.getDesignation().size() == theDesignationCount);
}
Optional<ValueSet.ValueSetExpansionContainsComponent> first = stream.findFirst();
if (!first.isPresent()) {
String failureMessage = String.format("Expanded ValueSet %s did not contain concept [%s|%s|%s] with [%d] designations", theValueSet.getId(), theSystem, theCode, theDisplay, theDesignationCount);
fail(failureMessage);
return null;
} else {
return first.get();
}
}
public List<String> getExpandedConceptsByValueSetUrl(String theValuesetUrl) { public List<String> getExpandedConceptsByValueSetUrl(String theValuesetUrl) {
return runInTransaction(() -> { return runInTransaction(() -> {
Optional<TermValueSet> valueSetOpt = myTermSvc.findCurrentTermValueSet(theValuesetUrl); Optional<TermValueSet> valueSetOpt = myTermSvc.findCurrentTermValueSet(theValuesetUrl);
assertTrue(valueSetOpt.isPresent()); assertTrue(valueSetOpt.isPresent());
TermValueSet valueSet = valueSetOpt.get(); TermValueSet valueSet = valueSetOpt.get();
List<TermValueSetConcept> concepts = valueSet.getConcepts(); List<TermValueSetConcept> concepts = valueSet.getConcepts();
return concepts.stream().map(concept -> concept.getCode()).collect(Collectors.toList()); return concepts.stream().map(TermValueSetConcept::getCode).collect(Collectors.toList());
}); });
} }
@ -557,103 +487,4 @@ public abstract class BaseJpaR5Test extends BaseJpaTest implements ITestDataBuil
myJpaValidationSupportChain.invalidateCaches(); myJpaValidationSupportChain.invalidateCaches();
} }
/**
* Creates a single {@link ConceptMap} entity that includes:
* <br>
* <ul>
* <li>
* One group with two elements, each identifying one target apiece.
* </li>
* <li>
* One group with one element, identifying two targets.
* </li>
* <li>
* One group with one element, identifying a target that also appears
* in the first element of the first group.
* </li>
* </ul>
* </br>
* The first two groups identify the same source code system and different target code systems.
* </br>
* The first two groups also include an element with the same source code.
*
* @return A {@link ConceptMap} entity for testing.
*/
public static ConceptMap createConceptMap() {
ConceptMap conceptMap = new ConceptMap();
conceptMap.setUrl(CM_URL);
conceptMap.setSourceScope(new UriType(VS_URL));
conceptMap.setTargetScope(new UriType(VS_URL_2));
ConceptMapGroupComponent group = conceptMap.addGroup();
group.setSource(CS_URL + "|" + "Version 1");
group.setTarget(CS_URL_2 + "|" + "Version 2");
SourceElementComponent element = group.addElement();
element.setCode("12345");
element.setDisplay("Source Code 12345");
TargetElementComponent target = element.addTarget();
target.setCode("34567");
target.setDisplay("Target Code 34567");
target.setRelationship(Enumerations.ConceptMapRelationship.EQUIVALENT);
element = group.addElement();
element.setCode("23456");
element.setDisplay("Source Code 23456");
target = element.addTarget();
target.setCode("45678");
target.setDisplay("Target Code 45678");
target.setRelationship(Enumerations.ConceptMapRelationship.SOURCEISBROADERTHANTARGET);
// Add a duplicate
target = element.addTarget();
target.setCode("45678");
target.setDisplay("Target Code 45678");
target.setRelationship(Enumerations.ConceptMapRelationship.SOURCEISBROADERTHANTARGET);
group = conceptMap.addGroup();
group.setSource(CS_URL + "|" + "Version 3");
group.setTarget(CS_URL_3 + "|" + "Version 4");
element = group.addElement();
element.setCode("12345");
element.setDisplay("Source Code 12345");
target = element.addTarget();
target.setCode("56789");
target.setDisplay("Target Code 56789");
target.setRelationship(Enumerations.ConceptMapRelationship.EQUIVALENT);
target = element.addTarget();
target.setCode("67890");
target.setDisplay("Target Code 67890");
target.setRelationship(Enumerations.ConceptMapRelationship.SOURCEISBROADERTHANTARGET);
group = conceptMap.addGroup();
group.setSource(CS_URL_4 + "|" + "Version 5");
group.setTarget(CS_URL_2 + "|" + "Version 2");
element = group.addElement();
element.setCode("78901");
element.setDisplay("Source Code 78901");
target = element.addTarget();
target.setCode("34567");
target.setDisplay("Target Code 34567");
target.setRelationship(Enumerations.ConceptMapRelationship.SOURCEISNARROWERTHANTARGET);
return conceptMap;
}
public static String toSearchUuidFromLinkNext(Bundle theBundle) {
String linkNext = theBundle.getLink("next").getUrl();
linkNext = linkNext.substring(linkNext.indexOf('?'));
Map<String, String[]> params = UrlUtil.parseQueryString(linkNext);
String[] uuidParams = params.get(Constants.PARAM_PAGINGACTION);
return uuidParams[0];
}
} }

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -118,6 +118,7 @@ import org.hl7.fhir.exceptions.FHIRException;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
@ -348,6 +349,9 @@ public abstract class BaseJpaDstu3Test extends BaseJpaTest {
@Autowired @Autowired
private IBulkDataExportJobSchedulingHelper myBulkDataScheduleHelper; private IBulkDataExportJobSchedulingHelper myBulkDataScheduleHelper;
@RegisterExtension
private final PreventDanglingInterceptorsExtension myPreventDanglingInterceptorsExtension = new PreventDanglingInterceptorsExtension(()-> myInterceptorRegistry);
@AfterEach() @AfterEach()
public void afterCleanupDao() { public void afterCleanupDao() {
myDaoConfig.setExpireSearchResults(new DaoConfig().isExpireSearchResults()); myDaoConfig.setExpireSearchResults(new DaoConfig().isExpireSearchResults());
@ -360,7 +364,6 @@ public abstract class BaseJpaDstu3Test extends BaseJpaTest {
@AfterEach @AfterEach
public void afterResetInterceptors() { public void afterResetInterceptors() {
super.afterResetInterceptors(); super.afterResetInterceptors();
myInterceptorRegistry.unregisterAllInterceptors();
} }
@AfterEach @AfterEach

View File

@ -517,7 +517,7 @@ public abstract class BaseJpaR4Test extends BaseJpaTest implements ITestDataBuil
private IBulkDataExportJobSchedulingHelper myBulkDataScheduleHelper; private IBulkDataExportJobSchedulingHelper myBulkDataScheduleHelper;
@RegisterExtension @RegisterExtension
private PreventDanglingInterceptorsExtension myPreventDanglingInterceptorsExtension = new PreventDanglingInterceptorsExtension(()-> myInterceptorRegistry); private final PreventDanglingInterceptorsExtension myPreventDanglingInterceptorsExtension = new PreventDanglingInterceptorsExtension(()-> myInterceptorRegistry);
@AfterEach() @AfterEach()
public void afterCleanupDao() { public void afterCleanupDao() {
@ -538,8 +538,7 @@ public abstract class BaseJpaR4Test extends BaseJpaTest implements ITestDataBuil
@Order(Integer.MIN_VALUE) @Order(Integer.MIN_VALUE)
@BeforeEach @BeforeEach
public void beforeResetInterceptors() { public void beforeResetInterceptors() {
// FIXME: restore? // nothing
// myInterceptorRegistry.unregisterAllInterceptors();
} }
@Override @Override
@ -548,9 +547,6 @@ public abstract class BaseJpaR4Test extends BaseJpaTest implements ITestDataBuil
public void afterResetInterceptors() { public void afterResetInterceptors() {
super.afterResetInterceptors(); super.afterResetInterceptors();
myInterceptorRegistry.unregisterInterceptor(myPerformanceTracingLoggingInterceptor); myInterceptorRegistry.unregisterInterceptor(myPerformanceTracingLoggingInterceptor);
// FIXME: restore?
// myInterceptorRegistry.unregisterAllInterceptors();
} }
@AfterEach @AfterEach

View File

@ -1,15 +0,0 @@
package ca.uhn.fhir.jpa.testutil;
import org.apache.commons.io.IOUtils;
import org.junit.jupiter.api.Test;
public class SpringFileTest {
@Test
public void testNoBadResources() throws Exception {
String text = IOUtils.toString(SpringFileTest.class.getResourceAsStream("/hapi-fhir-server-resourceproviders-dstu2.xml"));
// assertThat(text, not(containsString("OperationDefinition")));
}
}

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId> <artifactId>hapi-fhir</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -7,7 +7,7 @@
<parent> <parent>
<artifactId>hapi-fhir-serviceloaders</artifactId> <artifactId>hapi-fhir-serviceloaders</artifactId>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@ -7,7 +7,7 @@
<parent> <parent>
<artifactId>hapi-fhir-serviceloaders</artifactId> <artifactId>hapi-fhir-serviceloaders</artifactId>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
@ -20,7 +20,7 @@
<dependency> <dependency>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-caching-api</artifactId> <artifactId>hapi-fhir-caching-api</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.github.ben-manes.caffeine</groupId> <groupId>com.github.ben-manes.caffeine</groupId>

View File

@ -7,7 +7,7 @@
<parent> <parent>
<artifactId>hapi-fhir-serviceloaders</artifactId> <artifactId>hapi-fhir-serviceloaders</artifactId>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@ -7,7 +7,7 @@
<parent> <parent>
<artifactId>hapi-fhir</artifactId> <artifactId>hapi-fhir</artifactId>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>hapi-fhir</artifactId> <artifactId>hapi-fhir</artifactId>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-spring-boot-samples</artifactId> <artifactId>hapi-fhir-spring-boot-samples</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
</parent> </parent>
<artifactId>hapi-fhir-spring-boot-sample-client-apache</artifactId> <artifactId>hapi-fhir-spring-boot-sample-client-apache</artifactId>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-spring-boot-samples</artifactId> <artifactId>hapi-fhir-spring-boot-samples</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
</parent> </parent>
<artifactId>hapi-fhir-spring-boot-sample-client-okhttp</artifactId> <artifactId>hapi-fhir-spring-boot-sample-client-okhttp</artifactId>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-spring-boot-samples</artifactId> <artifactId>hapi-fhir-spring-boot-samples</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
</parent> </parent>
<artifactId>hapi-fhir-spring-boot-sample-server-jersey</artifactId> <artifactId>hapi-fhir-spring-boot-sample-server-jersey</artifactId>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-spring-boot</artifactId> <artifactId>hapi-fhir-spring-boot</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
</parent> </parent>
<artifactId>hapi-fhir-spring-boot-samples</artifactId> <artifactId>hapi-fhir-spring-boot-samples</artifactId>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId> <artifactId>hapi-fhir</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version> <version>6.3.1-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -21,40 +21,23 @@ package ca.uhn.fhir.jpa.api.dao;
*/ */
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum.ResourceMetadataKeySupportingAnyResource; import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum.ResourceMetadataKeySupportingAnyResource;
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;
public final class MetadataKeyCurrentlyReindexing extends ResourceMetadataKeySupportingAnyResource<Boolean, Boolean> { public final class MetadataKeyCurrentlyReindexing extends ResourceMetadataKeyEnum<Boolean> {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
MetadataKeyCurrentlyReindexing(String theValue) { MetadataKeyCurrentlyReindexing(String theValue) {
super(theValue); super(theValue);
} }
@Override
public Boolean get(IAnyResource theResource) {
return (Boolean) theResource.getUserData(IDao.CURRENTLY_REINDEXING.name());
}
@Override @Override
public Boolean get(IResource theResource) { public Boolean get(IResource theResource) {
return (Boolean) theResource.getResourceMetadata().get(IDao.CURRENTLY_REINDEXING); return (Boolean) theResource.getResourceMetadata().get(IDao.CURRENTLY_REINDEXING);
} }
@Override
public void put(IAnyResource theResource, Boolean theObject) {
theResource.setUserData(IDao.CURRENTLY_REINDEXING.name(), theObject);
}
public void put(IBaseResource theResource, Boolean theValue) {
if (theResource instanceof IAnyResource) {
put((IAnyResource) theResource, theValue);
} else {
put((IResource) theResource, theValue);
}
}
@Override @Override
public void put(IResource theResource, Boolean theObject) { public void put(IResource theResource, Boolean theObject) {
theResource.getResourceMetadata().put(IDao.CURRENTLY_REINDEXING, theObject); theResource.getResourceMetadata().put(IDao.CURRENTLY_REINDEXING, theObject);

Some files were not shown because too many files have changed in this diff Show More