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>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version>
<version>6.3.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<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>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<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>
</parent>

View File

@ -29,6 +29,7 @@ import ca.uhn.fhir.model.valueset.BundleEntryTransactionMethodEnum;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import org.apache.commons.lang3.StringUtils;
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 java.io.Serializable;
@ -64,6 +65,23 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
*/
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
* 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>
* </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;
@Override
public InstantDt get(IResource theResource) {
return getInstantFromMetadataOrNullIfNone(theResource.getResourceMetadata(), DELETED_AT);
}
@SuppressWarnings("unchecked")
@Override
public IPrimitiveType<Date> get(IAnyResource theResource) {
return (IPrimitiveType<Date>) theResource.getUserData(DELETED_AT.name());
public IPrimitiveType<Date> get(IResource theResource) {
return (IPrimitiveType<Date>) theResource.getResourceMetadata().get(this);
}
@Override
public void put(IResource theResource, InstantDt theObject) {
theResource.getResourceMetadata().put(DELETED_AT, theObject);
public void put(IResource theResource, IPrimitiveType<Date> 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 java.io.IOException;
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.zip.GZIPInputStream;
@ -86,6 +89,10 @@ public class ClasspathUtil {
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
*/

View File

@ -107,6 +107,7 @@ public enum VersionEnum {
V6_1_4,
V6_2_0,
V6_2_1,
// Dev Build
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.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.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
*/

View File

@ -8,6 +8,7 @@ import java.util.stream.Collectors;
import static org.hamcrest.CoreMatchers.hasItem;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class VersionEnumTest {
@ -18,10 +19,25 @@ public class VersionEnumTest {
.collect(Collectors.toList());
String version = VersionUtil.getVersion();
version = "V" + version.replace(".", "_");
version = version.replaceAll("-PRE[0-9]+", "");
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));
}

View File

@ -3,14 +3,14 @@
<modelVersion>4.0.0</modelVersion>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-bom</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version>
<version>6.3.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>HAPI FHIR BOM</name>
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<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>
</parent>

View File

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

View File

@ -4,7 +4,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<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>
</parent>

View File

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

View File

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

View File

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

View File

@ -4,7 +4,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<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>
</parent>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<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>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<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>
</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.ValueSet;
import org.hl7.fhir.r5.model.CapabilityStatement;
import org.hl7.fhir.r5.model.SearchParameter;
import java.util.List;
import static org.apache.commons.lang3.StringUtils.isBlank;
/**
* This class converts versions of various resources to/from a canonical version
* 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_40_50 ADVISOR_40_50 = new BaseAdvisor_40_50(false);
private static final BaseAdvisor_43_50 ADVISOR_43_50 = new BaseAdvisor_43_50(false);
@SuppressWarnings("rawtypes")
private final IStrategy myStrategy;
public VersionCanonicalizer(FhirContext theTargetContext) {
this(theTargetContext.getVersion().getVersion());
}
@SuppressWarnings("EnumSwitchStatementWhichMissesCases")
@SuppressWarnings({"EnumSwitchStatementWhichMissesCases", "EnhancedSwitchMigration"})
public VersionCanonicalizer(FhirVersionEnum theTargetVersion) {
switch (theTargetVersion) {
case DSTU2:
@ -160,9 +162,13 @@ public class VersionCanonicalizer {
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);
@ -175,9 +181,11 @@ public class VersionCanonicalizer {
IBaseResource valueSetFromCanonical(ValueSet theValueSet);
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();
@ -189,7 +197,7 @@ public class VersionCanonicalizer {
}
@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);
return (CapabilityStatement) VersionConvertorFactory_10_50.convertResource(reencoded, ADVISOR_10_50);
}
@ -224,8 +232,7 @@ public class VersionCanonicalizer {
@Override
public ValueSet valueSetToCanonical(IBaseResource theValueSet) {
org.hl7.fhir.dstu2.model.Resource reencoded = reencodeToHl7Org(theValueSet);
ValueSet valueSet = (ValueSet) VersionConvertorFactory_10_40.convertResource(reencoded, ADVISOR_10_40);
return valueSet;
return (ValueSet) VersionConvertorFactory_10_40.convertResource(reencoded, ADVISOR_10_40);
}
@Override
@ -275,6 +282,16 @@ public class VersionCanonicalizer {
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) {
if (myHl7OrgStructures) {
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
public CapabilityStatement capabilityStatementToCanonical(org.hl7.fhir.dstu3.model.Resource theCapabilityStatement) {
return (CapabilityStatement) VersionConvertorFactory_30_50.convertResource(theCapabilityStatement, ADVISOR_30_50);
public CapabilityStatement capabilityStatementToCanonical(IBaseResource theCapabilityStatement) {
return (CapabilityStatement) VersionConvertorFactory_30_50.convertResource((org.hl7.fhir.dstu3.model.Resource) theCapabilityStatement, ADVISOR_30_50);
}
@Override
@ -327,12 +344,17 @@ public class VersionCanonicalizer {
public ConceptMap conceptMapToCanonical(IBaseResource theConceptMap) {
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
public CapabilityStatement capabilityStatementToCanonical(org.hl7.fhir.r4.model.Resource theCapabilityStatement) {
return (CapabilityStatement) VersionConvertorFactory_40_50.convertResource(theCapabilityStatement, ADVISOR_40_50);
public CapabilityStatement capabilityStatementToCanonical(IBaseResource theCapabilityStatement) {
return (CapabilityStatement) VersionConvertorFactory_40_50.convertResource((org.hl7.fhir.r4.model.Resource) theCapabilityStatement, ADVISOR_40_50);
}
@Override
@ -365,13 +387,18 @@ public class VersionCanonicalizer {
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
public CapabilityStatement capabilityStatementToCanonical(org.hl7.fhir.r4b.model.Resource theCapabilityStatement) {
return (CapabilityStatement) VersionConvertorFactory_43_50.convertResource(theCapabilityStatement, ADVISOR_43_50);
public CapabilityStatement capabilityStatementToCanonical(IBaseResource theCapabilityStatement) {
return (CapabilityStatement) VersionConvertorFactory_43_50.convertResource((org.hl7.fhir.r4b.model.Resource) theCapabilityStatement, ADVISOR_43_50);
}
@Override
@ -410,13 +437,18 @@ public class VersionCanonicalizer {
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
public CapabilityStatement capabilityStatementToCanonical(org.hl7.fhir.r5.model.Resource theCapabilityStatement) {
public CapabilityStatement capabilityStatementToCanonical(IBaseResource 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);
}
@Override
public SearchParameter searchParameterToCanonical(IBaseResource theSearchParameter) {
return (SearchParameter) theSearchParameter;
}
}

View File

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

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<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>
</parent>

View File

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

View File

@ -6,6 +6,7 @@
<ul>
<li>SLF4j (All): 1.7.33 -> 2.0.3</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>Jetty (CLI): 9.4.48.v20220622 -> 10.0.12</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.
<a href="/hapi-fhir/docs/images/interceptors-server-pipeline.svg" target="_blank">Expand</a>
<img src="/hapi-fhir/docs/images/interceptors-server-pipeline.svg" alt="Server Pipeline"/>
<a href="server_pointcuts/interceptors-server-pipeline.svg" target="_blank">Expand</a>
<img src="server_pointcuts/interceptors-server-pipeline.svg" alt="Server Pipeline"/>
# 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.
<a href="/hapi-fhir/docs/images/interceptors-server-jpa-pipeline.svg" target="_blank">Expand</a>
<img src="/hapi-fhir/docs/images/interceptors-server-jpa-pipeline.svg" alt="Server Pipeline"/>
<a href="server_pointcuts/interceptors-server-jpa-pipeline.svg" target="_blank">Expand</a>
<img src="server_pointcuts/interceptors-server-jpa-pipeline.svg" alt="Server Pipeline"/>

View File

@ -11,7 +11,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<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>
</parent>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<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>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<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>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<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>
</parent>

View File

@ -84,7 +84,7 @@ public class JpaJobPersistenceImpl implements IJobPersistence {
}
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW)
@Transactional(propagation = Propagation.REQUIRED)
public String storeWorkChunk(BatchWorkChunk theBatchWorkChunk) {
Batch2WorkChunkEntity entity = new Batch2WorkChunkEntity();
entity.setId(UUID.randomUUID().toString());
@ -102,7 +102,7 @@ public class JpaJobPersistenceImpl implements IJobPersistence {
}
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW)
@Transactional(propagation = Propagation.REQUIRED)
public Optional<WorkChunk> fetchWorkChunkSetStartTimeAndMarkInProgress(String theChunkId) {
myWorkChunkRepository.updateChunkStatusForStart(theChunkId, new Date(), StatusEnum.IN_PROGRESS);
Optional<Batch2WorkChunkEntity> chunk = myWorkChunkRepository.findById(theChunkId);
@ -110,7 +110,7 @@ public class JpaJobPersistenceImpl implements IJobPersistence {
}
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW)
@Transactional(propagation = Propagation.REQUIRED)
public String storeNewInstance(JobInstance theInstance) {
Validate.isTrue(isBlank(theInstance.getInstanceId()));
@ -271,7 +271,7 @@ public class JpaJobPersistenceImpl implements IJobPersistence {
}
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW)
@Transactional(propagation = Propagation.REQUIRED)
public boolean canAdvanceInstanceToNextStep(String theInstanceId, String 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);

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.ISearchBuilder;
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.TransactionProcessor;
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.sp.ISearchParamPresenceSvc;
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.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.ITermReadSvc;
import ca.uhn.fhir.jpa.term.api.ITermReindexingSvc;
import ca.uhn.fhir.jpa.term.config.TermCodeSystemConfig;
import ca.uhn.fhir.jpa.util.MemoryCacheService;
import ca.uhn.fhir.jpa.validation.ResourceLoaderImpl;
@ -763,4 +768,22 @@ public class JpaConfig {
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.config.GeneratedDaoAndResourceProviderConfigDstu3;
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.dstu3.TransactionProcessorVersionAdapterDstu3;
import ca.uhn.fhir.jpa.graphql.GraphQLProvider;
@ -53,7 +52,6 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
@Import({
FhirContextDstu3Config.class,
GeneratedDaoAndResourceProviderConfigDstu3.class,
SharedConfigDstu3Plus.class,
JpaConfig.class
})
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.config.GeneratedDaoAndResourceProviderConfigR4;
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.r4.TransactionProcessorVersionAdapterR4;
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.ITermLoaderSvc;
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 org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.Consent;
@ -62,7 +60,6 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
@Import({
FhirContextR4Config.class,
GeneratedDaoAndResourceProviderConfigR4.class,
SharedConfigDstu3Plus.class,
JpaConfig.class
})
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.config.GeneratedDaoAndResourceProviderConfigR4B;
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.r4b.TransactionProcessorVersionAdapterR4B;
import ca.uhn.fhir.jpa.graphql.GraphQLProvider;
@ -53,7 +52,6 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
@Import({
FhirContextR4BConfig.class,
GeneratedDaoAndResourceProviderConfigR4B.class,
SharedConfigDstu3Plus.class,
JpaConfig.class
})
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.config.GeneratedDaoAndResourceProviderConfigR5;
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.r5.TransactionProcessorVersionAdapterR5;
import ca.uhn.fhir.jpa.graphql.GraphQLProvider;
@ -53,7 +52,6 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
@Import({
FhirContextR5Config.class,
GeneratedDaoAndResourceProviderConfigR5.class,
SharedConfigDstu3Plus.class,
JpaConfig.class
})
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
@ -21,7 +21,6 @@ package ca.uhn.fhir.jpa.dao.r4;
*/
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;
@ -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.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.r4.model.Composition;
@ -36,7 +36,7 @@ import org.hl7.fhir.r4.model.Composition;
import javax.servlet.http.HttpServletRequest;
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
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.searchparam.SearchParameterMap;
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.SortSpec;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
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.TransactionDetails;
import ca.uhn.fhir.rest.param.ReferenceOrListParam;
import ca.uhn.fhir.rest.param.ReferenceParam;
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.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.Date;
import java.util.List;
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
ObservationLastNIndexPersistSvc myObservationLastNIndexPersistSvc;
@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);
}
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,
Date theDeletedTimestampOrNull, boolean thePerformIndexing, boolean theUpdateVersion,
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.FhirVersionEnum;
@ -6,18 +6,18 @@ import ca.uhn.fhir.context.RuntimeSearchParam;
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.api.config.DaoConfig;
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.searchparam.extractor.ISearchParamExtractor;
import ca.uhn.fhir.rest.api.server.RequestDetails;
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.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.r4.model.CodeType;
import org.hl7.fhir.r4.model.Enumerations;
import org.hl7.fhir.r4.model.SearchParameter;
import org.hl7.fhir.r5.model.CodeType;
import org.hl7.fhir.r5.model.Enumerations;
import org.hl7.fhir.r5.model.SearchParameter;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
@ -46,60 +46,63 @@ import static org.apache.commons.lang3.StringUtils.isBlank;
* #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].*");
@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;
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);
}
@Override
protected void postPersist(ResourceTable theEntity, SearchParameter theResource, RequestDetails theRequestDetails) {
protected void postPersist(ResourceTable theEntity, T theResource, RequestDetails theRequestDetails) {
super.postPersist(theEntity, theResource, theRequestDetails);
reindexAffectedResources(theResource, theRequestDetails);
}
@Override
protected void postUpdate(ResourceTable theEntity, SearchParameter theResource, RequestDetails theRequestDetails) {
protected void postUpdate(ResourceTable theEntity, T theResource, RequestDetails theRequestDetails) {
super.postUpdate(theEntity, theResource, theRequestDetails);
reindexAffectedResources(theResource, theRequestDetails);
}
@Override
protected void preDelete(SearchParameter theResourceToDelete, ResourceTable theEntityToDelete, RequestDetails theRequestDetails) {
protected void preDelete(T theResourceToDelete, ResourceTable theEntityToDelete, RequestDetails theRequestDetails) {
super.preDelete(theResourceToDelete, theEntityToDelete, theRequestDetails);
reindexAffectedResources(theResourceToDelete, theRequestDetails);
}
@Override
protected void validateResourceForStorage(SearchParameter theResource, ResourceTable theEntityToSave) {
protected void validateResourceForStorage(T theResource, ResourceTable 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
* doing that
*/
if (theDaoConfig.getModelConfig().isDefaultSearchParamsCanBeOverridden() == false) {
for (IPrimitiveType<?> nextBaseType : theResource.getBase()) {
for (IPrimitiveType<?> nextBaseType : searchParameter.getBase()) {
String nextBase = nextBaseType.getValueAsString();
RuntimeSearchParam existingSearchParam = theSearchParamRegistry.getActiveSearchParam(nextBase, theResource.getCode());
RuntimeSearchParam existingSearchParam = mySearchParamRegistry.getActiveSearchParam(nextBase, searchParameter.getCode());
if (existingSearchParam != null) {
boolean isBuiltIn = existingSearchParam.getId() == null;
isBuiltIn |= existingSearchParam.getUri().startsWith("http://hl7.org/fhir/SearchParameter/");
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
* 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");
}
if (!theResource.getStatus().name().equals("ACTIVE")) {
if (!searchParameter.getStatus().name().equals("ACTIVE")) {
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");
}
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
} else if (isBlank(theResource.getExpression())) {
} else if (isBlank(searchParameter.getExpression())) {
throw new UnprocessableEntityException(Msg.code(1114) + "SearchParameter.expression is missing");
} else {
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");
}
for (SearchParameter.SearchParameterComponentComponent next : theResource.getComponent()) {
for (SearchParameter.SearchParameterComponentComponent next : searchParameter.getComponent()) {
if (isBlank(next.getDefinition())) {
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();
if (fhirVersion.isOlderThan(FhirVersionEnum.DSTU3)) {
// omitting validation for DSTU2_HL7ORG, DSTU2_1 and DSTU2
}
else {
} else {
if (theDaoConfig.isValidateSearchParameterExpressionsOnSave()) {
validateExpressionPath(theResource);
validateExpressionPath(searchParameter);
String expression = getExpression(theResource);
String expression = getExpression(searchParameter);
try {
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);
boolean isResourceOfTypeComposite = theSearchParameter.getType() == Enumerations.SearchParamType.COMPOSITE;
@ -175,23 +182,23 @@ public class FhirResourceDaoSearchParameterR4 extends BaseHapiFhirResourceDao<Se
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");
}
}
private static String getExpression(SearchParameter theSearchParameter){
private static String getExpression(SearchParameter theSearchParameter) {
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);
return theSearchParameter
.getExtensionsByUrl(HapiExtensions.EXT_SP_UNIQUE)
.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>
<groupId>ca.uhn.hapi.fhir</groupId>
<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>
</parent>

View File

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

View File

@ -6,7 +6,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<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>
</parent>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<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>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<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>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<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>
</parent>

View File

@ -179,6 +179,7 @@ public class SearchParameterCanonicalizer {
String path = theNextSp.getExpression();
RestSearchParameterTypeEnum paramType = null;
RuntimeSearchParam.RuntimeSearchParamStatusEnum status = null;
if (theNextSp.getType() != null) {
switch (theNextSp.getType()) {
case COMPOSITE:
paramType = RestSearchParameterTypeEnum.COMPOSITE;
@ -207,6 +208,7 @@ public class SearchParameterCanonicalizer {
case NULL:
break;
}
}
if (theNextSp.getStatus() != null) {
switch (theNextSp.getStatus()) {
case ACTIVE:

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<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>
</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.rest.api.EncodingEnum;
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.UnprocessableEntityException;
import ca.uhn.fhir.util.HapiExtensions;
@ -94,7 +95,12 @@ public class SubscriptionValidatingInterceptor {
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;
if (subscription.getStatus() == null) {
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>
<groupId>ca.uhn.hapi.fhir</groupId>
<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>
</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.subscription.match.registry.SubscriptionLoader;
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.util.ResourceCountCache;
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.BeforeEach;
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.Qualifier;
import org.springframework.context.ApplicationContext;
@ -213,6 +215,9 @@ public abstract class BaseJpaDstu2Test extends BaseJpaTest {
@Autowired
private ValidationSupportChain myJpaValidationSupportChain;
@RegisterExtension
private final PreventDanglingInterceptorsExtension myPreventDanglingInterceptorsExtension = new PreventDanglingInterceptorsExtension(()-> myInterceptorRegistry);
@BeforeEach
public void beforeFlushFT() {
purgeHibernateSearch(myEntityManager);
@ -232,13 +237,6 @@ public abstract class BaseJpaDstu2Test extends BaseJpaTest {
myDaoConfig.setAllowExternalReferences(new DaoConfig().isAllowExternalReferences());
}
@Override
@AfterEach
public void afterResetInterceptors() {
super.afterResetInterceptors();
myInterceptorRegistry.unregisterAllInterceptors();
}
@Override
public FhirContext getFhirContext() {
return myFhirContext;

View File

@ -58,6 +58,7 @@ public class SubscriptionsDstu2Test extends BaseResourceProviderDstu2Test {
Subscription subs = new Subscription();
subs.getChannel().setType(SubscriptionChannelTypeEnum.REST_HOOK);
subs.setCriteria("Observation?identifier=123");
subs.getChannel().setEndpoint("http://localhost");
try {
myClient.create().resource(subs).execute();
fail();
@ -105,6 +106,7 @@ public class SubscriptionsDstu2Test extends BaseResourceProviderDstu2Test {
public void testCreateWithPopulatedButInvalidStatue() {
Subscription subs = new Subscription();
subs.getChannel().setType(SubscriptionChannelTypeEnum.WEBSOCKET);
subs.getChannel().setEndpoint("http://localhost");
subs.setCriteria("Observation?identifier=123");
subs.getStatusElement().setValue("aaaaa");
@ -112,7 +114,7 @@ public class SubscriptionsDstu2Test extends BaseResourceProviderDstu2Test {
myClient.create().resource(subs).execute();
fail();
} 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();
subs.getChannel().setType(SubscriptionChannelTypeEnum.REST_HOOK);
subs.setCriteria("Observation?identifier=123");
subs.getChannel().setEndpoint("http://localhost");
subs.setStatus(SubscriptionStatusEnum.REQUESTED);
IIdType id = myClient.create().resource(subs).execute().getId();
subs.setId(id);

View File

@ -6,7 +6,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<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>
</parent>

View File

@ -93,7 +93,7 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu
}
@Test
public void testCreateSpWithMultiplePaths(){
public void testCreateSpWithMultiplePaths() {
SearchParameter sp = new SearchParameter();
sp.setCode("telephone-unformatted");
sp.setStatus(Enumerations.PublicationStatus.ACTIVE);
@ -101,18 +101,56 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu
sp.getBase().add(new CodeType("Patient"));
sp.setType(Enumerations.SearchParamType.TOKEN);
DaoMethodOutcome daoMethodOutcome = mySearchParameterDao.create(sp);
DaoMethodOutcome daoMethodOutcome;
daoMethodOutcome = mySearchParameterDao.create(sp);
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.setCode("telephone-unformatted-2");
daoMethodOutcome = mySearchParameterDao.create(sp);
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.setCode("telephone-unformatted-3");
daoMethodOutcome = mySearchParameterDao.create(sp);
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.setCode("telephone-unformatted-3");
@ -120,7 +158,6 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu
assertThat(daoMethodOutcome.getId(), is(notNullValue()));
}
@Test
public void testCreateInvalidParamNoPath() {
SearchParameter fooSp = new SearchParameter();
@ -1111,20 +1148,20 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu
myMedicationAdministrationDao.create(medAdmin);
runInTransaction(()->{
runInTransaction(() -> {
List<ResourceIndexedSearchParamToken> tokens = myResourceIndexedSearchParamTokenDao
.findAll()
.stream()
.filter(t -> t.getParamName().equals("medicationadministration-ingredient-medication"))
.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(false, tokens.get(0).isMissing());
});
SearchParameterMap map = SearchParameterMap.newSynchronous();
map.add("medicationadministration-ingredient-medication", new TokenParam("system","code"));
map.add("medicationadministration-ingredient-medication", new TokenParam("system", "code"));
myCaptureQueriesListener.clear();
IBundleProvider search = myMedicationAdministrationDao.search(map);
myCaptureQueriesListener.logSelectQueriesForCurrentThread();
@ -1133,5 +1170,4 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu
}
}

View File

@ -6,7 +6,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<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>
</parent>

View File

@ -404,18 +404,6 @@ public class Batch2CoordinatorIT extends BaseJpaR4Test {
@Test
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
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.RuntimeResourceDefinition;
@ -6,6 +6,7 @@ import ca.uhn.fhir.context.RuntimeSearchParam;
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.api.config.DaoConfig;
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.SearchParameter;
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;
@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 FhirResourceDaoSearchParameterR4 myDao;
private JpaResourceDaoSearchParameter<SearchParameter> myDao;
@Mock
private ApplicationContext myApplicationContext;
@ -34,10 +35,13 @@ public class FhirResourceDaoSearchParameterR4Test {
public void before() {
myCtx = FhirContext.forR4Cached();
myDao = new FhirResourceDaoSearchParameterR4();
VersionCanonicalizer versionCanonicalizer = new VersionCanonicalizer(myCtx);
myDao = new JpaResourceDaoSearchParameter<>();
myDao.setContext(myCtx);
myDao.setDaoConfigForUnitTest(new DaoConfig());
myDao.setApplicationContext(myApplicationContext);
myDao.setVersionCanonicalizerForUnitTest(versionCanonicalizer);
myDao.start();
}
@ -58,7 +62,7 @@ public class FhirResourceDaoSearchParameterR4Test {
nextSearchParameter.setExpression(nextp.getPath());
nextSearchParameter.setStatus(Enumerations.PublicationStatus.ACTIVE);
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());
myDao.validateResourceForStorage(nextSearchParameter, null);

View File

@ -6,7 +6,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<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>
</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.ITermDeferredStorageSvc;
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.util.ResourceCountCache;
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.BeforeEach;
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.Qualifier;
import org.springframework.context.ApplicationContext;
@ -382,6 +384,7 @@ public abstract class BaseJpaR4BTest extends BaseJpaTest implements ITestDataBui
@Autowired
private IBulkDataExportJobSchedulingHelper myBulkDataSchedulerHelper;
@Override
public IIdType doCreateResource(IBaseResource theResource) {
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);
}
@Override
@AfterEach
public void afterResetInterceptors() {
myInterceptorRegistry.unregisterAllInterceptors();
super.afterResetInterceptors();
myInterceptorRegistry.unregisterInterceptor(myPerformanceTracingLoggingInterceptor);
}
@AfterEach()

View File

@ -6,7 +6,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<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>
</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.ITermReadSvc;
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.util.ResourceCountCache;
import ca.uhn.fhir.parser.IParser;
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.interceptor.IServerInterceptor;
import ca.uhn.fhir.rest.server.provider.ResourceProviderFactory;
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.IIdType;
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.CompartmentDefinition;
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.Consent;
import org.hl7.fhir.r5.model.Coverage;
import org.hl7.fhir.r5.model.Device;
import org.hl7.fhir.r5.model.DiagnosticReport;
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.Immunization;
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.Substance;
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.utils.validation.constants.BestPracticeWarningLevel;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
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.Qualifier;
import org.springframework.context.ApplicationContext;
@ -142,22 +131,16 @@ import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Optional;
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.fail;
import static org.mockito.Mockito.mock;
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {TestR5Config.class})
public abstract class BaseJpaR5Test extends BaseJpaTest implements ITestDataBuilder {
private static IValidationSupport ourJpaValidationSupportChainR5;
private static IFhirResourceDaoValueSet<ValueSet> ourValueSetDao;
@Autowired
protected ITermCodeSystemStorageSvc myTermCodeSystemStorageSvc;
@Autowired
@ -401,8 +384,10 @@ public abstract class BaseJpaR5Test extends BaseJpaTest implements ITestDataBuil
protected ITermDeferredStorageSvc myTermDeferredStorageSvc;
@Autowired
private IValidationSupport myJpaValidationSupportChain;
@RegisterExtension
private PreventDanglingInterceptorsExtension myPreventDanglingInterceptorsExtension = new PreventDanglingInterceptorsExtension(() -> myInterceptorRegistry);
private PerformanceTracingLoggingInterceptor myPerformanceTracingLoggingInterceptor;
private List<Object> mySystemInterceptors;
@Autowired
private DaoRegistry myDaoRegistry;
@Autowired
@ -438,13 +423,6 @@ public abstract class BaseJpaR5Test extends BaseJpaTest implements ITestDataBuil
myPagingProvider.setMaximumPageSize(BasePagingProvider.DEFAULT_MAX_PAGE_SIZE);
}
@Override
@AfterEach
public void afterResetInterceptors() {
super.afterResetInterceptors();
myInterceptorRegistry.unregisterAllInterceptors();
}
@AfterEach
public void afterClearTerminologyCaches() {
TermReadSvcImpl baseHapiTerminologySvc = AopTestUtils.getTargetObject(myTermSvc);
@ -455,16 +433,15 @@ public abstract class BaseJpaR5Test extends BaseJpaTest implements ITestDataBuil
deferredStorageSvc.clearDeferred();
}
@AfterEach()
public void afterGrabCaches() {
ourValueSetDao = myValueSetDao;
ourJpaValidationSupportChainR5 = myJpaValidationSupportChain;
@AfterEach
@Override
protected void afterResetInterceptors() {
super.afterResetInterceptors();
myInterceptorRegistry.unregisterInterceptor(myPerformanceTracingLoggingInterceptor);
}
@BeforeEach
public void beforeCreateInterceptor() {
mySystemInterceptors = myInterceptorRegistry.getAllRegisteredInterceptors();
myInterceptor = mock(IServerInterceptor.class);
myPerformanceTracingLoggingInterceptor = new PerformanceTracingLoggingInterceptor();
@ -495,60 +472,13 @@ public abstract class BaseJpaR5Test extends BaseJpaTest implements ITestDataBuil
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) {
return runInTransaction(() -> {
Optional<TermValueSet> valueSetOpt = myTermSvc.findCurrentTermValueSet(theValuesetUrl);
assertTrue(valueSetOpt.isPresent());
TermValueSet valueSet = valueSetOpt.get();
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();
}
/**
* 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>
<groupId>ca.uhn.hapi.fhir</groupId>
<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>
</parent>

View File

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

View File

@ -517,7 +517,7 @@ public abstract class BaseJpaR4Test extends BaseJpaTest implements ITestDataBuil
private IBulkDataExportJobSchedulingHelper myBulkDataScheduleHelper;
@RegisterExtension
private PreventDanglingInterceptorsExtension myPreventDanglingInterceptorsExtension = new PreventDanglingInterceptorsExtension(()-> myInterceptorRegistry);
private final PreventDanglingInterceptorsExtension myPreventDanglingInterceptorsExtension = new PreventDanglingInterceptorsExtension(()-> myInterceptorRegistry);
@AfterEach()
public void afterCleanupDao() {
@ -538,8 +538,7 @@ public abstract class BaseJpaR4Test extends BaseJpaTest implements ITestDataBuil
@Order(Integer.MIN_VALUE)
@BeforeEach
public void beforeResetInterceptors() {
// FIXME: restore?
// myInterceptorRegistry.unregisterAllInterceptors();
// nothing
}
@Override
@ -548,9 +547,6 @@ public abstract class BaseJpaR4Test extends BaseJpaTest implements ITestDataBuil
public void afterResetInterceptors() {
super.afterResetInterceptors();
myInterceptorRegistry.unregisterInterceptor(myPerformanceTracingLoggingInterceptor);
// FIXME: restore?
// myInterceptorRegistry.unregisterAllInterceptors();
}
@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>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId>
<version>6.3.0-PRE5-SNAPSHOT</version>
<version>6.3.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -7,7 +7,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<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>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<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>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<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>
</parent>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<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>
</parent>

View File

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

View File

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

View File

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

View File

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

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<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>
</parent>

View File

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

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<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>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<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>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<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>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<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>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<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>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<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>
</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.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum.ResourceMetadataKeySupportingAnyResource;
import org.hl7.fhir.instance.model.api.IAnyResource;
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;
MetadataKeyCurrentlyReindexing(String theValue) {
super(theValue);
}
@Override
public Boolean get(IAnyResource theResource) {
return (Boolean) theResource.getUserData(IDao.CURRENTLY_REINDEXING.name());
}
@Override
public Boolean get(IResource theResource) {
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
public void put(IResource theResource, Boolean theObject) {
theResource.getResourceMetadata().put(IDao.CURRENTLY_REINDEXING, theObject);

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