pathList = paramDefinition.getPathsSplitForResourceType(resourceType);
+
Condition subQueryCondition = ComboCondition.and(
BinaryCondition.equalTo(
getResourceIdColumn(),
theParams.getResourceTablePredicateBuilder().getResourceIdColumn()),
- BinaryCondition.equalTo(
- getResourceTypeColumn(),
- generatePlaceholder(
- theParams.getResourceTablePredicateBuilder().getResourceType())));
+ BinaryCondition.equalTo(getResourceTypeColumn(), generatePlaceholder(resourceType)),
+ ComboCondition.or(pathList.stream()
+ .map(path -> BinaryCondition.equalTo(getColumnSourcePath(), generatePlaceholder(path)))
+ .toArray(BinaryCondition[]::new)));
subquery.addCondition(subQueryCondition);
diff --git a/hapi-fhir-jpaserver-elastic-test-utilities/pom.xml b/hapi-fhir-jpaserver-elastic-test-utilities/pom.xml
index 541c6bcf8e4..63278c80de9 100644
--- a/hapi-fhir-jpaserver-elastic-test-utilities/pom.xml
+++ b/hapi-fhir-jpaserver-elastic-test-utilities/pom.xml
@@ -6,7 +6,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-hfql/pom.xml b/hapi-fhir-jpaserver-hfql/pom.xml
index c3518186230..b645a59783e 100644
--- a/hapi-fhir-jpaserver-hfql/pom.xml
+++ b/hapi-fhir-jpaserver-hfql/pom.xml
@@ -3,7 +3,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-ips/pom.xml b/hapi-fhir-jpaserver-ips/pom.xml
index c3bb21c52f4..854a185fe21 100644
--- a/hapi-fhir-jpaserver-ips/pom.xml
+++ b/hapi-fhir-jpaserver-ips/pom.xml
@@ -3,7 +3,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-mdm/pom.xml b/hapi-fhir-jpaserver-mdm/pom.xml
index c0b4ddef5d2..33f317dc5d5 100644
--- a/hapi-fhir-jpaserver-mdm/pom.xml
+++ b/hapi-fhir-jpaserver-mdm/pom.xml
@@ -6,7 +6,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-model/pom.xml b/hapi-fhir-jpaserver-model/pom.xml
index 9ee46575c6e..3eb70e0326c 100644
--- a/hapi-fhir-jpaserver-model/pom.xml
+++ b/hapi-fhir-jpaserver-model/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/config/PartitionSettings.java b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/config/PartitionSettings.java
index f077d3baf0e..379f8098f23 100644
--- a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/config/PartitionSettings.java
+++ b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/config/PartitionSettings.java
@@ -34,6 +34,7 @@ public class PartitionSettings {
private boolean myAlwaysOpenNewTransactionForDifferentPartition;
private boolean myConditionalCreateDuplicateIdentifiersEnabled = false;
+ public PartitionSettings() {}
/**
* Should we always open a new database transaction if the partition context changes
*
diff --git a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceTable.java b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceTable.java
index e897ae71786..6163011eeb4 100644
--- a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceTable.java
+++ b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceTable.java
@@ -119,21 +119,6 @@ public class ResourceTable extends BaseHasResource implements Serializable, IBas
searchable = Searchable.YES,
projectable = Projectable.YES,
analyzer = "standardAnalyzer")
- @FullTextField(
- name = "myContentTextEdgeNGram",
- searchable = Searchable.YES,
- projectable = Projectable.NO,
- analyzer = "autocompleteEdgeAnalyzer")
- @FullTextField(
- name = "myContentTextNGram",
- searchable = Searchable.YES,
- projectable = Projectable.NO,
- analyzer = "autocompleteNGramAnalyzer")
- @FullTextField(
- name = "myContentTextPhonetic",
- searchable = Searchable.YES,
- projectable = Projectable.NO,
- analyzer = "autocompletePhoneticAnalyzer")
@OptimisticLock(excluded = true)
@IndexingDependency(derivedFrom = @ObjectPath(@PropertyValue(propertyName = "myVersion")))
private String myContentText;
@@ -171,21 +156,6 @@ public class ResourceTable extends BaseHasResource implements Serializable, IBas
searchable = Searchable.YES,
projectable = Projectable.YES,
analyzer = "standardAnalyzer")
- @FullTextField(
- name = "myNarrativeTextEdgeNGram",
- searchable = Searchable.YES,
- projectable = Projectable.NO,
- analyzer = "autocompleteEdgeAnalyzer")
- @FullTextField(
- name = "myNarrativeTextNGram",
- searchable = Searchable.YES,
- projectable = Projectable.NO,
- analyzer = "autocompleteNGramAnalyzer")
- @FullTextField(
- name = "myNarrativeTextPhonetic",
- searchable = Searchable.YES,
- projectable = Projectable.NO,
- analyzer = "autocompletePhoneticAnalyzer")
@OptimisticLock(excluded = true)
@IndexingDependency(derivedFrom = @ObjectPath(@PropertyValue(propertyName = "myVersion")))
private String myNarrativeText;
diff --git a/hapi-fhir-jpaserver-searchparam/pom.xml b/hapi-fhir-jpaserver-searchparam/pom.xml
index 7c33dcd01cc..1a24fcf3297 100755
--- a/hapi-fhir-jpaserver-searchparam/pom.xml
+++ b/hapi-fhir-jpaserver-searchparam/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/ISearchParamExtractor.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/ISearchParamExtractor.java
index 77a43ddc2e5..e8d1755c780 100644
--- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/ISearchParamExtractor.java
+++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/ISearchParamExtractor.java
@@ -44,13 +44,13 @@ public interface ISearchParamExtractor {
/**
* Constant for the {@literal theSearchParamFilter} parameters on this interface
- * indicating that all search parameters should be indexed.
+ * indicating that all search parameters should be extracted.
*/
ISearchParamFilter ALL_PARAMS = t -> t;
/**
* Constant for the {@literal theSearchParamFilter} parameters on this interface
- * indicating that no search parameters should be indexed.
+ * indicating that no search parameters should be extracted.
*/
ISearchParamFilter NO_PARAMS = t -> Collections.emptyList();
@@ -155,7 +155,7 @@ public interface ISearchParamExtractor {
interface ISearchParamFilter {
/**
- * Given the list of search parameters for indexing, an implementation of this
+ * Given the list of search parameters for extracting, an implementation of this
* interface may selectively remove any that it wants to remove (or can add if desired).
*
* Implementations must not modify the list that is passed in. If changes are
diff --git a/hapi-fhir-jpaserver-subscription/pom.xml b/hapi-fhir-jpaserver-subscription/pom.xml
index 4e85901e5e9..ba09eed0ab5 100644
--- a/hapi-fhir-jpaserver-subscription/pom.xml
+++ b/hapi-fhir-jpaserver-subscription/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-test-dstu2/pom.xml b/hapi-fhir-jpaserver-test-dstu2/pom.xml
index fe968fe84cb..c3f924fd915 100644
--- a/hapi-fhir-jpaserver-test-dstu2/pom.xml
+++ b/hapi-fhir-jpaserver-test-dstu2/pom.xml
@@ -6,7 +6,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-test-dstu3/pom.xml b/hapi-fhir-jpaserver-test-dstu3/pom.xml
index e8d0f1f6bb4..d665c0f3c97 100644
--- a/hapi-fhir-jpaserver-test-dstu3/pom.xml
+++ b/hapi-fhir-jpaserver-test-dstu3/pom.xml
@@ -6,7 +6,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-test-r4/pom.xml b/hapi-fhir-jpaserver-test-r4/pom.xml
index 548d7257155..86ac609723f 100644
--- a/hapi-fhir-jpaserver-test-r4/pom.xml
+++ b/hapi-fhir-jpaserver-test-r4/pom.xml
@@ -6,7 +6,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4ReferentialIntegrityTest.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4ReferentialIntegrityTest.java
index f75fce4b44c..8020f0556ea 100644
--- a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4ReferentialIntegrityTest.java
+++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4ReferentialIntegrityTest.java
@@ -1,19 +1,26 @@
package ca.uhn.fhir.jpa.dao.r4;
-import static org.junit.jupiter.api.Assertions.assertEquals;
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
import ca.uhn.fhir.jpa.test.BaseJpaR4Test;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException;
+import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import org.hl7.fhir.instance.model.api.IIdType;
+import org.hl7.fhir.r4.model.IdType;
+import org.hl7.fhir.r4.model.Observation;
import org.hl7.fhir.r4.model.Organization;
import org.hl7.fhir.r4.model.Patient;
import org.hl7.fhir.r4.model.Reference;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
-import static org.assertj.core.api.Assertions.assertThat;
+import java.util.stream.Stream;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
public class FhirResourceDaoR4ReferentialIntegrityTest extends BaseJpaR4Test {
@@ -23,51 +30,168 @@ public class FhirResourceDaoR4ReferentialIntegrityTest extends BaseJpaR4Test {
myStorageSettings.setEnforceReferentialIntegrityOnWrite(new JpaStorageSettings().isEnforceReferentialIntegrityOnWrite());
myStorageSettings.setEnforceReferentialIntegrityOnDelete(new JpaStorageSettings().isEnforceReferentialIntegrityOnDelete());
myStorageSettings.setEnforceReferenceTargetTypes(new JpaStorageSettings().isEnforceReferenceTargetTypes());
+ myStorageSettings.setResourceClientIdStrategy(new JpaStorageSettings().getResourceClientIdStrategy());
+ }
+
+ @ParameterizedTest
+ @MethodSource("paramsProvider_withResourceType")
+ public void referentialIntegrityOnWriteSetting_unknownIds_fullScopeTest(boolean theIsEnforceRefIntegrityEnabled,
+ JpaStorageSettings.ClientIdStrategyEnum theClientIdStrategy,
+ String theReferenceId) {
+ // Given
+ myStorageSettings.setEnforceReferentialIntegrityOnWrite(theIsEnforceRefIntegrityEnabled);
+ myStorageSettings.setEnforceReferenceTargetTypes(theIsEnforceRefIntegrityEnabled);
+ myStorageSettings.setResourceClientIdStrategy(theClientIdStrategy);
+
+ Patient p = new Patient();
+ p.setManagingOrganization(new Reference(theReferenceId));
+
+ if (theIsEnforceRefIntegrityEnabled) {
+ try {
+ // When
+ myPatientDao.create(p);
+ fail();
+ } catch (InvalidRequestException e) {
+ // Then
+ assertEquals(Msg.code(1094) + "Resource " + theReferenceId + " not found, specified in path: Patient.managingOrganization", e.getMessage());
+ }
+ } else {
+ // Disabled ref integrity on write case: all POSTs should succeed
+ // When
+ IIdType id = myPatientDao.create(p).getId().toUnqualifiedVersionless();
+ // Then
+ p = myPatientDao.read(id);
+ assertEquals(theReferenceId, p.getManagingOrganization().getReference());
+ }
+ }
+
+ private static Stream paramsProvider_withResourceType() {
+ // theIsEnforceRefIntegrityEnabled, theClientIdStrategy, theReferenceId
+ // note: client ID is tested since resolving the resource reference is different depending on the strategy
+ return Stream.of(
+ Arguments.of(true, JpaStorageSettings.ClientIdStrategyEnum.ALPHANUMERIC, "Organization/123"),
+ Arguments.of(true, JpaStorageSettings.ClientIdStrategyEnum.ALPHANUMERIC, "Organization/A123"),
+ Arguments.of(true, JpaStorageSettings.ClientIdStrategyEnum.ANY, "Organization/123"),
+ Arguments.of(true, JpaStorageSettings.ClientIdStrategyEnum.ANY, "Organization/A123"),
+ Arguments.of(false, JpaStorageSettings.ClientIdStrategyEnum.ALPHANUMERIC, "Organization/123"),
+ Arguments.of(false, JpaStorageSettings.ClientIdStrategyEnum.ALPHANUMERIC, "Organization/A123"),
+ Arguments.of(false, JpaStorageSettings.ClientIdStrategyEnum.ANY, "Organization/123"),
+ Arguments.of(false, JpaStorageSettings.ClientIdStrategyEnum.ANY, "Organization/A123")
+ );
}
@Test
- public void testCreateUnknownReferenceFail() throws Exception {
+ public void testRefIntegrityOnWrite_withReferenceIdOfAnotherResourceType() {
+ // Given
+ myStorageSettings.setResourceClientIdStrategy(JpaStorageSettings.ClientIdStrategyEnum.ALPHANUMERIC);
+ // Create Observation with some ID...
+ Observation obs = new Observation();
+ IIdType obsId = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
+
+ // And reference a non-existing Organization resource with the same ID as the Observation
Patient p = new Patient();
- p.setManagingOrganization(new Reference("Organization/AAA"));
+ p.setManagingOrganization(new Reference(new IdType("Organization", obsId.getIdPart())));
+
try {
+ // When
myPatientDao.create(p);
fail();
- } catch (InvalidRequestException e) {
- assertEquals(Msg.code(1094) + "Resource Organization/AAA not found, specified in path: Patient.managingOrganization", e.getMessage());
+ } catch (UnprocessableEntityException e) {
+ // Then: identify that it is the wrong resource type, since ref integrity is enabled
+ assertEquals(Msg.code(1095) + "Resource contains reference to unknown resource ID Organization/" + obsId.getIdPart(), e.getMessage());
}
+ // Given: now disable referential integrity on write
+ myStorageSettings.setEnforceReferentialIntegrityOnWrite(false);
+ // When
+ IIdType id = myPatientDao.create(p).getId().toUnqualifiedVersionless();
+ // Then: this should now succeed
+ p = myPatientDao.read(id);
+ assertEquals("Organization/" + obsId.getIdPart(), p.getManagingOrganization().getReference());
}
- @Test
- public void testCreateUnknownReferenceAllowed() {
- myStorageSettings.setEnforceReferentialIntegrityOnWrite(false);
+ @ParameterizedTest
+ @MethodSource("paramsProvider_noResourceType")
+ public void testRefIntegrityOnWrite_withValidReferenceId_shouldAlwaysSucceed(boolean theIsEnforceRefIntegrityEnabled,
+ JpaStorageSettings.ClientIdStrategyEnum theClientIdStrategy,
+ String theReferenceId) {
+ // Given
+ myStorageSettings.setEnforceReferentialIntegrityOnWrite(theIsEnforceRefIntegrityEnabled);
+ myStorageSettings.setEnforceReferenceTargetTypes(theIsEnforceRefIntegrityEnabled);
+ myStorageSettings.setResourceClientIdStrategy(theClientIdStrategy);
+
+ Organization obs = new Organization();
+ obs.setId(theReferenceId);
+ myOrganizationDao.update(obs, mySrd);
+ String qualifiedReferenceId = "Organization/" + theReferenceId;
Patient p = new Patient();
- p.setManagingOrganization(new Reference("Organization/AAA"));
+ p.setManagingOrganization(new Reference(qualifiedReferenceId));
+
+ // When
IIdType id = myPatientDao.create(p).getId().toUnqualifiedVersionless();
+ // Then
p = myPatientDao.read(id);
- assertEquals("Organization/AAA", p.getManagingOrganization().getReference());
-
+ assertEquals(qualifiedReferenceId, p.getManagingOrganization().getReference());
}
- @Test
- public void testCreateUnknownReferenceAllowed_NumericId() {
- myStorageSettings.setEnforceReferentialIntegrityOnWrite(false);
- myStorageSettings.setEnforceReferenceTargetTypes(false);
+ private static Stream paramsProvider_noResourceType() {
+ // theIsEnforceRefIntegrityEnabled, theClientIdStrategy, theReferenceId
+ // note: client ID is tested since resolving the resource reference is different depending on the strategy
+ return Stream.of(
+ Arguments.of(true, JpaStorageSettings.ClientIdStrategyEnum.ALPHANUMERIC, "A123"),
+ Arguments.of(true, JpaStorageSettings.ClientIdStrategyEnum.ANY, "123"),
+ Arguments.of(true, JpaStorageSettings.ClientIdStrategyEnum.ANY, "A123"),
+ Arguments.of(false, JpaStorageSettings.ClientIdStrategyEnum.ALPHANUMERIC, "A123"),
+ Arguments.of(false, JpaStorageSettings.ClientIdStrategyEnum.ANY, "123"),
+ Arguments.of(false, JpaStorageSettings.ClientIdStrategyEnum.ANY, "A123")
+ );
+ }
+
+ @ParameterizedTest
+ @MethodSource("paramsProvider_noResourceType")
+ public void testRefIntegrityOnWrite_withReferenceIdOfDeletedResource(boolean theIsEnforceRefIntegrityEnabled,
+ JpaStorageSettings.ClientIdStrategyEnum theClientIdStrategy,
+ String theReferenceId) {
+ // Given
+ myStorageSettings.setEnforceReferentialIntegrityOnWrite(theIsEnforceRefIntegrityEnabled);
+ myStorageSettings.setEnforceReferenceTargetTypes(theIsEnforceRefIntegrityEnabled);
+ myStorageSettings.setResourceClientIdStrategy(theClientIdStrategy);
+
+ Organization obs = new Organization();
+ obs.setId(theReferenceId);
+ IIdType obsId = myOrganizationDao.update(obs, mySrd).getId();
+ String qualifiedReferenceId = "Organization/" + theReferenceId;
+
+ myOrganizationDao.delete(obsId, mySrd);
Patient p = new Patient();
- p.setManagingOrganization(new Reference("Organization/123"));
- IIdType id = myPatientDao.create(p).getId().toUnqualifiedVersionless();
+ p.setManagingOrganization(new Reference(qualifiedReferenceId));
- p = myPatientDao.read(id);
- assertEquals("Organization/123", p.getManagingOrganization().getReference());
+ if (theIsEnforceRefIntegrityEnabled) {
+ try {
+ // When
+ myPatientDao.create(p);
+ fail();
+ } catch (InvalidRequestException e) {
+ // Then
+ assertEquals(Msg.code(1096) + "Resource " + qualifiedReferenceId + " is deleted, specified in path: Patient.managingOrganization", e.getMessage());
+ }
+ } else {
+ // Disabled ref integrity on write case: all POSTs should succeed
+ // When
+ IIdType id = myPatientDao.create(p).getId().toUnqualifiedVersionless();
+ // Then
+ p = myPatientDao.read(id);
+ assertEquals(qualifiedReferenceId, p.getManagingOrganization().getReference());
+ }
}
@Test
- public void testDeleteFail() throws Exception {
+ public void testDeleteFail() {
Organization o = new Organization();
o.setName("FOO");
IIdType oid = myOrganizationDao.create(o).getId().toUnqualifiedVersionless();
@@ -89,7 +213,7 @@ public class FhirResourceDaoR4ReferentialIntegrityTest extends BaseJpaR4Test {
}
@Test
- public void testDeleteAllow() throws Exception {
+ public void testDeleteAllow() {
myStorageSettings.setEnforceReferentialIntegrityOnDelete(false);
Organization o = new Organization();
diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchMissingTest.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchMissingTest.java
index 742fb1ed48d..811ea570e2f 100644
--- a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchMissingTest.java
+++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchMissingTest.java
@@ -1,9 +1,10 @@
package ca.uhn.fhir.jpa.dao.r4;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import ca.uhn.fhir.i18n.Msg;
-import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
import ca.uhn.fhir.jpa.model.entity.NormalizedQuantitySearchLevel;
+import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamCoords;
+import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamQuantity;
+import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamQuantityNormalized;
+import ca.uhn.fhir.jpa.model.entity.StorageSettings;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.test.BaseJpaR4Test;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
@@ -12,7 +13,6 @@ import ca.uhn.fhir.rest.param.QuantityParam;
import ca.uhn.fhir.rest.param.ReferenceParam;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.param.TokenParam;
-import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.DateType;
import org.hl7.fhir.r4.model.DecimalType;
@@ -26,513 +26,528 @@ import org.hl7.fhir.r4.model.Reference;
import org.hl7.fhir.r4.model.Task;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.stream.Collectors;
import static org.assertj.core.api.Assertions.assertThat;
-public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test {
- private static final Logger ourLog = LoggerFactory.getLogger(FhirResourceDaoR4SearchMissingTest.class);
+public class FhirResourceDaoR4SearchMissingTest {
- @BeforeEach
- public void beforeResetMissing() {
- myStorageSettings.setIndexMissingFields(JpaStorageSettings.IndexEnabledEnum.ENABLED);
- }
-
- @AfterEach
- public void afterResetSearch() {
- myStorageSettings.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_NOT_SUPPORTED);
- }
-
- @Test
- public void testIndexMissingFieldsDisabledDontAllowInSearch_NonReference() {
- myStorageSettings.setIndexMissingFields(JpaStorageSettings.IndexEnabledEnum.DISABLED);
-
- SearchParameterMap params = new SearchParameterMap();
- params.add(Patient.SP_ACTIVE, new StringParam().setMissing(true));
- try {
- myPatientDao.search(params);
- } catch (MethodNotAllowedException e) {
- assertEquals(Msg.code(985) + ":missing modifier is disabled on this server", e.getMessage());
+ @Nested
+ class IndexMissingDisabledTests extends MissingTests {
+ @BeforeEach
+ public void before() {
+ myStorageSettings.setIndexMissingFields(StorageSettings.IndexEnabledEnum.DISABLED);
}
- }
- @Test
- public void testIndexMissingFieldsDisabledDontAllowInSearch_Reference() {
- myStorageSettings.setIndexMissingFields(JpaStorageSettings.IndexEnabledEnum.DISABLED);
-
- SearchParameterMap params = new SearchParameterMap();
- params.add(Patient.SP_ORGANIZATION, new StringParam().setMissing(true));
- try {
- myPatientDao.search(params);
- } catch (MethodNotAllowedException e) {
- assertEquals(Msg.code(985) + ":missing modifier is disabled on this server", e.getMessage());
- }
- }
-
- @Test
- public void testIndexMissingFieldsDisabledDontCreateIndexes() {
- myStorageSettings.setIndexMissingFields(JpaStorageSettings.IndexEnabledEnum.DISABLED);
- Organization org = new Organization();
- org.setActive(true);
- myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless();
-
- runInTransaction(() -> {
- assertThat(mySearchParamPresentDao.findAll()).isEmpty();
- assertThat(myResourceIndexedSearchParamStringDao.findAll()).isEmpty();
- assertThat(myResourceIndexedSearchParamDateDao.findAll()).isEmpty();
- assertThat(myResourceIndexedSearchParamTokenDao.findAll()).hasSize(1);
- assertThat(myResourceIndexedSearchParamQuantityDao.findAll()).isEmpty();
- });
-
- }
-
- @Test
- public void testIndexMissingFieldsDisabledDontCreateIndexesWithNormalizedQuantitySearchSupported() {
-
- myStorageSettings.setIndexMissingFields(JpaStorageSettings.IndexEnabledEnum.DISABLED);
- myStorageSettings.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED);
- Organization org = new Organization();
- org.setActive(true);
- myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless();
-
- runInTransaction(() -> {
- assertThat(mySearchParamPresentDao.findAll()).isEmpty();
- assertThat(myResourceIndexedSearchParamStringDao.findAll()).isEmpty();
- assertThat(myResourceIndexedSearchParamDateDao.findAll()).isEmpty();
- assertThat(myResourceIndexedSearchParamTokenDao.findAll()).hasSize(1);
- assertThat(myResourceIndexedSearchParamQuantityDao.findAll()).isEmpty();
- });
-
- }
-
- @Test
- public void testIndexMissingFieldsDisabledDontCreateIndexesWithNormalizedQuantityStorageSupported() {
-
- myStorageSettings.setIndexMissingFields(JpaStorageSettings.IndexEnabledEnum.DISABLED);
- myStorageSettings.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_STORAGE_SUPPORTED);
- Organization org = new Organization();
- org.setActive(true);
- myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless();
-
- runInTransaction(() -> {
- assertThat(mySearchParamPresentDao.findAll()).isEmpty();
- assertThat(myResourceIndexedSearchParamStringDao.findAll()).isEmpty();
- assertThat(myResourceIndexedSearchParamDateDao.findAll()).isEmpty();
- assertThat(myResourceIndexedSearchParamTokenDao.findAll()).hasSize(1);
- assertThat(myResourceIndexedSearchParamQuantityDao.findAll()).isEmpty();
- });
-
- }
-
- @SuppressWarnings("unused")
- @Test
- public void testSearchResourceReferenceMissingChain() {
- IIdType oid1;
- {
+ @Test
+ public void testIndexMissingFieldsDisabledDontCreateIndexes() {
Organization org = new Organization();
org.setActive(true);
- oid1 = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless();
- }
- IIdType tid1;
- {
- Task task = new Task();
- task.setRequester(new Reference(oid1));
- tid1 = myTaskDao.create(task, mySrd).getId().toUnqualifiedVersionless();
- }
- IIdType tid2;
- {
- Task task = new Task();
- task.setOwner(new Reference(oid1));
- tid2 = myTaskDao.create(task, mySrd).getId().toUnqualifiedVersionless();
+ myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless();
+
+ runInTransaction(() -> {
+ assertThat(mySearchParamPresentDao.findAll()).isEmpty();
+ assertThat(myResourceIndexedSearchParamStringDao.findAll()).isEmpty();
+ assertThat(myResourceIndexedSearchParamDateDao.findAll()).isEmpty();
+ assertThat(myResourceIndexedSearchParamTokenDao.findAll()).hasSize(1);
+ assertThat(myResourceIndexedSearchParamQuantityDao.findAll()).isEmpty();
+ });
+
}
- IIdType oid2;
- {
+ @Test
+ public void testIndexMissingFieldsDisabledDontCreateIndexesWithNormalizedQuantitySearchSupported() {
+ myStorageSettings.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED);
Organization org = new Organization();
org.setActive(true);
- org.setName("NAME");
- oid2 = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless();
- }
- IIdType tid3;
- {
- Task task = new Task();
- task.setRequester(new Reference(oid2));
- tid3 = myTaskDao.create(task, mySrd).getId().toUnqualifiedVersionless();
+ myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless();
+
+ runInTransaction(() -> {
+ assertThat(mySearchParamPresentDao.findAll()).isEmpty();
+ assertThat(myResourceIndexedSearchParamStringDao.findAll()).isEmpty();
+ assertThat(myResourceIndexedSearchParamDateDao.findAll()).isEmpty();
+ assertThat(myResourceIndexedSearchParamTokenDao.findAll()).hasSize(1);
+ assertThat(myResourceIndexedSearchParamQuantityDao.findAll()).isEmpty();
+ });
+
}
- SearchParameterMap map;
- List ids;
+ @Test
+ public void testIndexMissingFieldsDisabledDontCreateIndexesWithNormalizedQuantityStorageSupported() {
+ myStorageSettings.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_STORAGE_SUPPORTED);
+ Organization org = new Organization();
+ org.setActive(true);
+ myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless();
- map = new SearchParameterMap();
- map.add(Organization.SP_NAME, new StringParam().setMissing(true));
- ids = toUnqualifiedVersionlessIds(myOrganizationDao.search(map));
- assertThat(ids).containsExactly(oid1);
+ runInTransaction(() -> {
+ assertThat(mySearchParamPresentDao.findAll()).isEmpty();
+ assertThat(myResourceIndexedSearchParamStringDao.findAll()).isEmpty();
+ assertThat(myResourceIndexedSearchParamDateDao.findAll()).isEmpty();
+ assertThat(myResourceIndexedSearchParamTokenDao.findAll()).hasSize(1);
+ assertThat(myResourceIndexedSearchParamQuantityDao.findAll()).isEmpty();
+ });
- ourLog.info("Starting Search 2");
-
- map = new SearchParameterMap();
- map.add(Task.SP_REQUESTER, new ReferenceParam("Organization", "name:missing", "true"));
- ids = toUnqualifiedVersionlessIds(myTaskDao.search(map));
- assertThat(ids).containsExactly(tid1); // NOT tid2
-
- map = new SearchParameterMap();
- map.add(Task.SP_REQUESTER, new ReferenceParam("Organization", "name:missing", "false"));
- ids = toUnqualifiedVersionlessIds(myTaskDao.search(map));
- assertThat(ids).containsExactly(tid3);
-
- map = new SearchParameterMap();
- map.add(Patient.SP_ORGANIZATION, new ReferenceParam("Organization", "name:missing", "true"));
- ids = toUnqualifiedVersionlessIds(myPatientDao.search(map));
- assertThat(ids).isEmpty();
-
- }
-
- @Test
- public void testSearchWithMissingDate() {
- IIdType orgId = myOrganizationDao.create(new Organization(), mySrd).getId();
- IIdType notMissing;
- IIdType missing;
- {
- Patient patient = new Patient();
- patient.addIdentifier().setSystem("urn:system").setValue("001");
- missing = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
- }
- {
- Patient patient = new Patient();
- patient.addIdentifier().setSystem("urn:system").setValue("002");
- patient.addName().setFamily("Tester_testSearchStringParam").addGiven("John");
- patient.setBirthDateElement(new DateType("2011-01-01"));
- patient.getManagingOrganization().setReferenceElement(orgId);
- notMissing = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
- }
- // Date Param
- {
- SearchParameterMap params = new SearchParameterMap();
- params.setLoadSynchronous(true);
- DateParam param = new DateParam();
- param.setMissing(false);
- params.add(Patient.SP_BIRTHDATE, param);
- List patients = toUnqualifiedVersionlessIds(myPatientDao.search(params));
- assertThat(patients).containsSubsequence(notMissing);
- assertThat(patients).doesNotContainSubsequence(missing);
- }
- {
- SearchParameterMap params = new SearchParameterMap();
- params.setLoadSynchronous(true);
- DateParam param = new DateParam();
- param.setMissing(true);
- params.add(Patient.SP_BIRTHDATE, param);
- List patients = toUnqualifiedVersionlessIds(myPatientDao.search(params));
- assertThat(patients).containsSubsequence(missing);
- assertThat(patients).doesNotContainSubsequence(notMissing);
}
}
- @Test
- public void testSearchWithMissingCoords() {
- String locId = myLocationDao.create(new Location(), mySrd).getId().toUnqualifiedVersionless().getValue();
- String locId2 = myLocationDao.create(new Location().setPosition(new Location.LocationPositionComponent(new DecimalType(10), new DecimalType(10))), mySrd).getId().toUnqualifiedVersionless().getValue();
-
- runInTransaction(() -> {
- ourLog.info("Coords:\n * {}", myResourceIndexedSearchParamCoordsDao.findAll().stream().map(t -> t.toString()).collect(Collectors.joining("\n * ")));
- });
-
- {
- SearchParameterMap params = new SearchParameterMap();
- params.setLoadSynchronous(true);
- TokenParam param = new TokenParam();
- param.setMissing(true);
- params.add(Location.SP_NEAR, param);
- myCaptureQueriesListener.clear();
- List patients = toUnqualifiedVersionlessIdValues(myLocationDao.search(params));
- myCaptureQueriesListener.logSelectQueriesForCurrentThread(0);
- assertThat(patients).containsSubsequence(locId);
- assertThat(patients).doesNotContainSubsequence(locId2);
+ @Nested
+ class IndexMissingEnabledTests extends MissingTests {
+ @BeforeEach
+ public void before() {
+ myStorageSettings.setIndexMissingFields(StorageSettings.IndexEnabledEnum.ENABLED);
}
- {
- SearchParameterMap params = new SearchParameterMap();
- params.setLoadSynchronous(true);
- TokenParam param = new TokenParam();
- param.setMissing(false);
- params.add(Location.SP_NEAR, param);
- List patients = toUnqualifiedVersionlessIdValues(myLocationDao.search(params));
- assertThat(patients).containsSubsequence(locId2);
- assertThat(patients).doesNotContainSubsequence(locId);
+
+
+ @SuppressWarnings("unused")
+ @Test
+ public void testSearchResourceReferenceMissingChain() {
+ IIdType oid1;
+ {
+ Organization org = new Organization();
+ org.setActive(true);
+ oid1 = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless();
+ }
+ IIdType tid1;
+ {
+ Task task = new Task();
+ task.setRequester(new Reference(oid1));
+ tid1 = myTaskDao.create(task, mySrd).getId().toUnqualifiedVersionless();
+ }
+ {
+ Task task = new Task();
+ task.setOwner(new Reference(oid1));
+ myTaskDao.create(task, mySrd).getId().toUnqualifiedVersionless();
+ }
+
+ IIdType oid2;
+ {
+ Organization org = new Organization();
+ org.setActive(true);
+ org.setName("NAME");
+ oid2 = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless();
+ }
+ IIdType tid3;
+ {
+ Task task = new Task();
+ task.setRequester(new Reference(oid2));
+ tid3 = myTaskDao.create(task, mySrd).getId().toUnqualifiedVersionless();
+ }
+
+ SearchParameterMap map;
+ List ids;
+
+ map = new SearchParameterMap();
+ map.add(Organization.SP_NAME, new StringParam().setMissing(true));
+ ids = toUnqualifiedVersionlessIds(myOrganizationDao.search(map, mySrd));
+ assertThat(ids).containsExactly(oid1);
+
+ ourLog.info("Starting Search 2");
+
+ map = new SearchParameterMap();
+ map.add(Task.SP_REQUESTER, new ReferenceParam("Organization", "name:missing", "true"));
+ ids = toUnqualifiedVersionlessIds(myTaskDao.search(map, mySrd));
+ assertThat(ids).containsExactly(tid1); // NOT tid2
+
+ map = new SearchParameterMap();
+ map.add(Task.SP_REQUESTER, new ReferenceParam("Organization", "name:missing", "false"));
+ ids = toUnqualifiedVersionlessIds(myTaskDao.search(map, mySrd));
+ assertThat(ids).containsExactly(tid3);
+
+ map = new SearchParameterMap();
+ map.add(Patient.SP_ORGANIZATION, new ReferenceParam("Organization", "name:missing", "true"));
+ ids = toUnqualifiedVersionlessIds(myPatientDao.search(map, mySrd));
+ assertThat(ids).isEmpty();
+
}
}
- @Test
- public void testSearchWithMissingDate2() {
- MedicationRequest mr1 = new MedicationRequest();
- mr1.addCategory().addCoding().setSystem("urn:medicationroute").setCode("oral");
- mr1.addDosageInstruction().getTiming().addEventElement().setValueAsString("2017-01-01");
- IIdType id1 = myMedicationRequestDao.create(mr1).getId().toUnqualifiedVersionless();
+ static class MissingTests extends BaseJpaR4Test {
+ @AfterEach
+ public void after() {
+ myStorageSettings.setIndexMissingFields(new StorageSettings().getIndexMissingFields());
+ myStorageSettings.setNormalizedQuantitySearchLevel(new StorageSettings().getNormalizedQuantitySearchLevel());
- MedicationRequest mr2 = new MedicationRequest();
- mr2.addCategory().addCoding().setSystem("urn:medicationroute").setCode("oral");
- IIdType id2 = myMedicationRequestDao.create(mr2).getId().toUnqualifiedVersionless();
-
- SearchParameterMap map = new SearchParameterMap();
- map.add(MedicationRequest.SP_DATE, new DateParam().setMissing(true));
- IBundleProvider results = myMedicationRequestDao.search(map);
- List ids = toUnqualifiedVersionlessIdValues(results);
-
- assertThat(ids).containsExactly(id2.getValue());
-
- }
-
- @Test
- public void testSearchWithMissingQuantity() {
- IIdType notMissing;
- IIdType missing;
- {
- Observation obs = new Observation();
- obs.addIdentifier().setSystem("urn:system").setValue("001");
- missing = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
}
- {
- Observation obs = new Observation();
- obs.addIdentifier().setSystem("urn:system").setValue("002");
- obs.setValue(new Quantity(123));
- notMissing = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
+
+ @Test
+ public void testSearchWithMissingDate() {
+ IIdType orgId = myOrganizationDao.create(new Organization(), mySrd).getId();
+ IIdType notMissing;
+ IIdType missing;
+ {
+ Patient patient = new Patient();
+ patient.addIdentifier().setSystem("urn:system").setValue("001");
+ missing = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
+ }
+ {
+ Patient patient = new Patient();
+ patient.addIdentifier().setSystem("urn:system").setValue("002");
+ patient.addName().setFamily("Tester_testSearchStringParam").addGiven("John");
+ patient.setBirthDateElement(new DateType("2011-01-01"));
+ patient.getManagingOrganization().setReferenceElement(orgId);
+ notMissing = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
+ }
+ // Date Param
+ {
+ SearchParameterMap params = new SearchParameterMap();
+ params.setLoadSynchronous(true);
+ DateParam param = new DateParam();
+ param.setMissing(false);
+ params.add(Patient.SP_BIRTHDATE, param);
+ List patients = toUnqualifiedVersionlessIds(myPatientDao.search(params, mySrd));
+ assertThat(patients).containsSubsequence(notMissing);
+ assertThat(patients).doesNotContainSubsequence(missing);
+ }
+ {
+ SearchParameterMap params = new SearchParameterMap();
+ params.setLoadSynchronous(true);
+ DateParam param = new DateParam();
+ param.setMissing(true);
+ params.add(Patient.SP_BIRTHDATE, param);
+ List patients = toUnqualifiedVersionlessIds(myPatientDao.search(params, mySrd));
+ assertThat(patients).containsSubsequence(missing);
+ assertThat(patients).doesNotContainSubsequence(notMissing);
+ }
}
- // Quantity Param
- {
+
+ @Test
+ public void testSearchWithMissingCoords() {
+ String locId = myLocationDao.create(new Location(), mySrd).getId().toUnqualifiedVersionless().getValue();
+ String locId2 = myLocationDao.create(new Location().setPosition(new Location.LocationPositionComponent(new DecimalType(10), new DecimalType(10))), mySrd).getId().toUnqualifiedVersionless().getValue();
+
+ runInTransaction(() -> ourLog.info("Coords:\n * {}",
+ myResourceIndexedSearchParamCoordsDao.findAll().stream()
+ .map(ResourceIndexedSearchParamCoords::toString).collect(Collectors.joining("\n * "))
+ )
+ );
+
+ {
+ SearchParameterMap params = new SearchParameterMap();
+ params.setLoadSynchronous(true);
+ TokenParam param = new TokenParam();
+ param.setMissing(true);
+ params.add(Location.SP_NEAR, param);
+ myCaptureQueriesListener.clear();
+ List patients = toUnqualifiedVersionlessIdValues(myLocationDao.search(params, mySrd));
+ myCaptureQueriesListener.logSelectQueriesForCurrentThread(0);
+ assertThat(patients).containsSubsequence(locId);
+ assertThat(patients).doesNotContainSubsequence(locId2);
+ }
+ {
+ SearchParameterMap params = new SearchParameterMap();
+ params.setLoadSynchronous(true);
+ TokenParam param = new TokenParam();
+ param.setMissing(false);
+ params.add(Location.SP_NEAR, param);
+ List patients = toUnqualifiedVersionlessIdValues(myLocationDao.search(params, mySrd));
+ assertThat(patients).containsSubsequence(locId2);
+ assertThat(patients).doesNotContainSubsequence(locId);
+ }
+ }
+
+ @Test
+ public void testSearchWithMissingDate2() {
+ MedicationRequest mr1 = new MedicationRequest();
+ mr1.addCategory().addCoding().setSystem("urn:medicationroute").setCode("oral");
+ mr1.addDosageInstruction().getTiming().addEventElement().setValueAsString("2017-01-01");
+ myMedicationRequestDao.create(mr1, mySrd).getId().toUnqualifiedVersionless();
+
+ MedicationRequest mr2 = new MedicationRequest();
+ mr2.addCategory().addCoding().setSystem("urn:medicationroute").setCode("oral");
+ IIdType id2 = myMedicationRequestDao.create(mr2, mySrd).getId().toUnqualifiedVersionless();
+
+ SearchParameterMap map = new SearchParameterMap();
+ map.add(MedicationRequest.SP_DATE, new DateParam().setMissing(true));
+ IBundleProvider results = myMedicationRequestDao.search(map, mySrd);
+ List ids = toUnqualifiedVersionlessIdValues(results);
+
+ assertThat(ids).containsExactly(id2.getValue());
+
+ }
+
+ @Test
+ public void testSearchWithMissingQuantity() {
+ IIdType notMissing;
+ IIdType missing;
+ {
+ Observation obs = new Observation();
+ obs.addIdentifier().setSystem("urn:system").setValue("001");
+ missing = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
+ }
+ {
+ Observation obs = new Observation();
+ obs.addIdentifier().setSystem("urn:system").setValue("002");
+ obs.setValue(new Quantity(123));
+ notMissing = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
+ }
+ // Quantity Param
+ {
+ SearchParameterMap params = new SearchParameterMap();
+ params.setLoadSynchronous(true);
+ QuantityParam param = new QuantityParam();
+ param.setMissing(false);
+ params.add(Observation.SP_VALUE_QUANTITY, param);
+ List patients = toUnqualifiedVersionlessIds(myObservationDao.search(params, mySrd));
+ assertThat(patients).doesNotContainSubsequence(missing);
+ assertThat(patients).containsSubsequence(notMissing);
+ }
+ {
+ SearchParameterMap params = new SearchParameterMap();
+ params.setLoadSynchronous(true);
+ QuantityParam param = new QuantityParam();
+ param.setMissing(true);
+ params.add(Observation.SP_VALUE_QUANTITY, param);
+ List patients = toUnqualifiedVersionlessIds(myObservationDao.search(params, mySrd));
+ assertThat(patients).containsSubsequence(missing);
+ assertThat(patients).doesNotContainSubsequence(notMissing);
+ }
+ }
+
+ @Test
+ public void testSearchWithMissingQuantityWithNormalizedQuantitySearchSupported() {
+
+ myStorageSettings.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED);
+ IIdType notMissing;
+ IIdType missing;
+ {
+ Observation obs = new Observation();
+ obs.addIdentifier().setSystem("urn:system").setValue("001");
+ missing = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
+ }
+ {
+ Observation obs = new Observation();
+ obs.addIdentifier().setSystem("urn:system").setValue("002");
+ obs.setValue(new Quantity(123));
+ notMissing = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
+ }
+
+ runInTransaction(() -> {
+ ourLog.info("Quantity Indexes:\n * {}",
+ myResourceIndexedSearchParamQuantityDao.findAll().stream()
+ .filter(t -> t.getParamName().equals("value-quantity")).map(ResourceIndexedSearchParamQuantity::toString).collect(Collectors.joining("\n * ")
+ )
+ );
+ ourLog.info("Normalized Quantity Indexes:\n * {}",
+ myResourceIndexedSearchParamQuantityNormalizedDao.findAll().stream().
+ filter(t -> t.getParamName().equals("value-quantity")).map(ResourceIndexedSearchParamQuantityNormalized::toString).collect(Collectors.joining("\n * ")
+ )
+ );
+ });
+
+ // Quantity Param
+ {
+ SearchParameterMap params = new SearchParameterMap();
+ params.setLoadSynchronous(true);
+ QuantityParam param = new QuantityParam();
+ param.setMissing(false);
+ params.add(Observation.SP_VALUE_QUANTITY, param);
+ List patients = toUnqualifiedVersionlessIds(myObservationDao.search(params, mySrd));
+ assertThat(patients).doesNotContainSubsequence(missing);
+ assertThat(patients).containsSubsequence(notMissing);
+ }
+ {
+ SearchParameterMap params = new SearchParameterMap();
+ params.setLoadSynchronous(true);
+ QuantityParam param = new QuantityParam();
+ param.setMissing(true);
+ params.add(Observation.SP_VALUE_QUANTITY, param);
+ myCaptureQueriesListener.clear();
+ List patients = toUnqualifiedVersionlessIds(myObservationDao.search(params, mySrd));
+ myCaptureQueriesListener.logSelectQueries();
+ assertThat(patients).containsSubsequence(missing);
+ assertThat(patients).doesNotContainSubsequence(notMissing);
+ }
+
+ }
+
+ @Test
+ public void testSearchWithMissingQuantityWithNormalizedQuantityStorageSupported() {
+
+ myStorageSettings.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_STORAGE_SUPPORTED);
+ IIdType notMissing;
+ IIdType missing;
+ {
+ Observation obs = new Observation();
+ obs.addIdentifier().setSystem("urn:system").setValue("001");
+ missing = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
+ }
+ {
+ Observation obs = new Observation();
+ obs.addIdentifier().setSystem("urn:system").setValue("002");
+ obs.setValue(new Quantity(123));
+ notMissing = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
+ }
+ // Quantity Param
+ {
+ SearchParameterMap params = new SearchParameterMap();
+ params.setLoadSynchronous(true);
+ QuantityParam param = new QuantityParam();
+ param.setMissing(false);
+ params.add(Observation.SP_VALUE_QUANTITY, param);
+ List patients = toUnqualifiedVersionlessIds(myObservationDao.search(params, mySrd));
+ assertThat(patients).doesNotContainSubsequence(missing);
+ assertThat(patients).containsSubsequence(notMissing);
+ }
+ {
+ SearchParameterMap params = new SearchParameterMap();
+ params.setLoadSynchronous(true);
+ QuantityParam param = new QuantityParam();
+ param.setMissing(true);
+ params.add(Observation.SP_VALUE_QUANTITY, param);
+ List patients = toUnqualifiedVersionlessIds(myObservationDao.search(params, mySrd));
+ assertThat(patients).containsSubsequence(missing);
+ assertThat(patients).doesNotContainSubsequence(notMissing);
+ }
+
+ }
+
+
+ @Test
+ public void testSearchWithMissingReference() {
+ IIdType orgId = myOrganizationDao.create(new Organization(), mySrd).getId().toUnqualifiedVersionless();
+ IIdType notMissing;
+ IIdType missing;
+ {
+ Patient patient = new Patient();
+ patient.addIdentifier().setSystem("urn:system").setValue("001");
+ missing = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
+ }
+ {
+ Patient patient = new Patient();
+ patient.addIdentifier().setSystem("urn:system").setValue("002");
+ patient.addName().setFamily("Tester_testSearchStringParam").addGiven("John");
+ patient.setBirthDateElement(new DateType("2011-01-01"));
+ patient.getManagingOrganization().setReferenceElement(orgId);
+ notMissing = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
+ }
+ // Reference Param
+ {
+ SearchParameterMap params = new SearchParameterMap();
+ params.setLoadSynchronous(true);
+ ReferenceParam param = new ReferenceParam();
+ param.setMissing(false);
+ params.add(Patient.SP_ORGANIZATION, param);
+ List patients = toUnqualifiedVersionlessIds(myPatientDao.search(params, mySrd));
+ assertThat(patients).doesNotContainSubsequence(missing);
+ assertThat(patients).containsSubsequence(notMissing);
+ }
+ {
+ SearchParameterMap params = new SearchParameterMap();
+ params.setLoadSynchronous(true);
+ ReferenceParam param = new ReferenceParam();
+ param.setMissing(true);
+ params.add(Patient.SP_ORGANIZATION, param);
+ List patients = toUnqualifiedVersionlessIds(myPatientDao.search(params, mySrd));
+ assertThat(patients).containsSubsequence(missing);
+ assertThat(patients).doesNotContainSubsequence(notMissing);
+ assertThat(patients).doesNotContainSubsequence(orgId);
+ }
+ }
+
+
+ @Test
+ public void testSearchWithMissingReference_resourceTypeWithMultipleReferences() {
+ IIdType patientId = createPatient();
+ IIdType observationId = createObservation(withSubject(patientId));
+
SearchParameterMap params = new SearchParameterMap();
- params.setLoadSynchronous(true);
- QuantityParam param = new QuantityParam();
- param.setMissing(false);
- params.add(Observation.SP_VALUE_QUANTITY, param);
- List patients = toUnqualifiedVersionlessIds(myObservationDao.search(params));
- assertThat(patients).doesNotContainSubsequence(missing);
- assertThat(patients).containsSubsequence(notMissing);
+ params.add(Observation.SP_PERFORMER, new ReferenceParam().setMissing(true));
+ IBundleProvider bundleProvider = myObservationDao.search(params, mySrd);
+ assertThat(bundleProvider.getAllResourceIds()).containsExactly(observationId.getIdPart());
}
- {
+
+ @Test
+ public void testSearchWithMissingReference_searchParamMultiplePaths() {
+ IIdType encounterId = createEncounter();
+ createObservation(withEncounter(encounterId.getValue()));
+
SearchParameterMap params = new SearchParameterMap();
- params.setLoadSynchronous(true);
- QuantityParam param = new QuantityParam();
- param.setMissing(true);
- params.add(Observation.SP_VALUE_QUANTITY, param);
- List patients = toUnqualifiedVersionlessIds(myObservationDao.search(params));
- assertThat(patients).containsSubsequence(missing);
- assertThat(patients).doesNotContainSubsequence(notMissing);
- }
- }
-
- @Test
- public void testSearchWithMissingQuantityWithNormalizedQuantitySearchSupported() {
-
- myStorageSettings.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED);
- IIdType notMissing;
- IIdType missing;
- {
- Observation obs = new Observation();
- obs.addIdentifier().setSystem("urn:system").setValue("001");
- missing = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
- }
- {
- Observation obs = new Observation();
- obs.addIdentifier().setSystem("urn:system").setValue("002");
- obs.setValue(new Quantity(123));
- notMissing = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
+ params.add(Observation.SP_ENCOUNTER, new ReferenceParam().setMissing(true));
+ IBundleProvider bundleProvider = myObservationDao.search(params, mySrd);
+ assertThat(bundleProvider.getAllResourceIds()).isEmpty();
}
- runInTransaction(() -> {
- ourLog.info("Quantity Indexes:\n * {}", myResourceIndexedSearchParamQuantityDao.findAll().stream().filter(t -> t.getParamName().equals("value-quantity")).map(t -> t.toString()).collect(Collectors.joining("\n * ")));
- ourLog.info("Normalized Quantity Indexes:\n * {}", myResourceIndexedSearchParamQuantityNormalizedDao.findAll().stream().filter(t -> t.getParamName().equals("value-quantity")).map(t -> t.toString()).collect(Collectors.joining("\n * ")));
- });
-
- // Quantity Param
- {
- SearchParameterMap params = new SearchParameterMap();
- params.setLoadSynchronous(true);
- QuantityParam param = new QuantityParam();
- param.setMissing(false);
- params.add(Observation.SP_VALUE_QUANTITY, param);
- List patients = toUnqualifiedVersionlessIds(myObservationDao.search(params));
- assertThat(patients).doesNotContainSubsequence(missing);
- assertThat(patients).containsSubsequence(notMissing);
- }
- {
- SearchParameterMap params = new SearchParameterMap();
- params.setLoadSynchronous(true);
- QuantityParam param = new QuantityParam();
- param.setMissing(true);
- params.add(Observation.SP_VALUE_QUANTITY, param);
- myCaptureQueriesListener.clear();
- List patients = toUnqualifiedVersionlessIds(myObservationDao.search(params));
- myCaptureQueriesListener.logSelectQueries();
- assertThat(patients).containsSubsequence(missing);
- assertThat(patients).doesNotContainSubsequence(notMissing);
+ @Test
+ public void testSearchWithMissingString() {
+ IIdType orgId = myOrganizationDao.create(new Organization(), mySrd).getId();
+ IIdType notMissing;
+ IIdType missing;
+ {
+ Patient patient = new Patient();
+ patient.addIdentifier().setSystem("urn:system").setValue("001");
+ missing = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
+ }
+ {
+ Patient patient = new Patient();
+ patient.addIdentifier().setSystem("urn:system").setValue("002");
+ patient.addName().setFamily("Tester_testSearchStringParam").addGiven("John");
+ patient.setBirthDateElement(new DateType("2011-01-01"));
+ patient.getManagingOrganization().setReferenceElement(orgId);
+ notMissing = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
+ }
+ // String Param
+ {
+ SearchParameterMap params = new SearchParameterMap();
+ params.setLoadSynchronous(true);
+ StringParam param = new StringParam();
+ param.setMissing(false);
+ params.add(Patient.SP_FAMILY, param);
+ List patients = toUnqualifiedVersionlessIds(myPatientDao.search(params, mySrd));
+ assertThat(patients).doesNotContainSubsequence(missing);
+ assertThat(patients).containsSubsequence(notMissing);
+ }
+ {
+ SearchParameterMap params = new SearchParameterMap();
+ params.setLoadSynchronous(true);
+ StringParam param = new StringParam();
+ param.setMissing(true);
+ params.add(Patient.SP_FAMILY, param);
+ List patients = toUnqualifiedVersionlessIds(myPatientDao.search(params, mySrd));
+ assertThat(patients).containsSubsequence(missing);
+ assertThat(patients).doesNotContainSubsequence(notMissing);
+ }
}
- }
-
- @Test
- public void testSearchWithMissingQuantityWithNormalizedQuantityStorageSupported() {
-
- myStorageSettings.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_STORAGE_SUPPORTED);
- IIdType notMissing;
- IIdType missing;
- {
- Observation obs = new Observation();
- obs.addIdentifier().setSystem("urn:system").setValue("001");
- missing = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
- }
- {
- Observation obs = new Observation();
- obs.addIdentifier().setSystem("urn:system").setValue("002");
- obs.setValue(new Quantity(123));
- notMissing = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
- }
- // Quantity Param
- {
- SearchParameterMap params = new SearchParameterMap();
- params.setLoadSynchronous(true);
- QuantityParam param = new QuantityParam();
- param.setMissing(false);
- params.add(Observation.SP_VALUE_QUANTITY, param);
- List patients = toUnqualifiedVersionlessIds(myObservationDao.search(params));
- assertThat(patients).doesNotContainSubsequence(missing);
- assertThat(patients).containsSubsequence(notMissing);
- }
- {
- SearchParameterMap params = new SearchParameterMap();
- params.setLoadSynchronous(true);
- QuantityParam param = new QuantityParam();
- param.setMissing(true);
- params.add(Observation.SP_VALUE_QUANTITY, param);
- List patients = toUnqualifiedVersionlessIds(myObservationDao.search(params));
- assertThat(patients).containsSubsequence(missing);
- assertThat(patients).doesNotContainSubsequence(notMissing);
- }
-
- }
-
-
- @Test
- public void testSearchWithMissingReference() {
- IIdType orgId = myOrganizationDao.create(new Organization(), mySrd).getId().toUnqualifiedVersionless();
- IIdType notMissing;
- IIdType missing;
- {
- Patient patient = new Patient();
- patient.addIdentifier().setSystem("urn:system").setValue("001");
- missing = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
- }
- {
- Patient patient = new Patient();
- patient.addIdentifier().setSystem("urn:system").setValue("002");
- patient.addName().setFamily("Tester_testSearchStringParam").addGiven("John");
- patient.setBirthDateElement(new DateType("2011-01-01"));
- patient.getManagingOrganization().setReferenceElement(orgId);
- notMissing = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
- }
- // Reference Param
- {
- SearchParameterMap params = new SearchParameterMap();
- params.setLoadSynchronous(true);
- ReferenceParam param = new ReferenceParam();
- param.setMissing(false);
- params.add(Patient.SP_ORGANIZATION, param);
- List patients = toUnqualifiedVersionlessIds(myPatientDao.search(params));
- assertThat(patients).doesNotContainSubsequence(missing);
- assertThat(patients).containsSubsequence(notMissing);
- }
- {
- SearchParameterMap params = new SearchParameterMap();
- params.setLoadSynchronous(true);
- ReferenceParam param = new ReferenceParam();
- param.setMissing(true);
- params.add(Patient.SP_ORGANIZATION, param);
- List patients = toUnqualifiedVersionlessIds(myPatientDao.search(params));
- assertThat(patients).containsSubsequence(missing);
- assertThat(patients).doesNotContainSubsequence(notMissing);
- assertThat(patients).doesNotContainSubsequence(orgId);
- }
- }
-
- @Test
- public void testSearchWithMissingString() {
- IIdType orgId = myOrganizationDao.create(new Organization(), mySrd).getId();
- IIdType notMissing;
- IIdType missing;
- {
- Patient patient = new Patient();
- patient.addIdentifier().setSystem("urn:system").setValue("001");
- missing = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
- }
- {
- Patient patient = new Patient();
- patient.addIdentifier().setSystem("urn:system").setValue("002");
- patient.addName().setFamily("Tester_testSearchStringParam").addGiven("John");
- patient.setBirthDateElement(new DateType("2011-01-01"));
- patient.getManagingOrganization().setReferenceElement(orgId);
- notMissing = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
- }
- // String Param
- {
- SearchParameterMap params = new SearchParameterMap();
- params.setLoadSynchronous(true);
- StringParam param = new StringParam();
- param.setMissing(false);
- params.add(Patient.SP_FAMILY, param);
- List patients = toUnqualifiedVersionlessIds(myPatientDao.search(params));
- assertThat(patients).doesNotContainSubsequence(missing);
- assertThat(patients).containsSubsequence(notMissing);
- }
- {
- SearchParameterMap params = new SearchParameterMap();
- params.setLoadSynchronous(true);
- StringParam param = new StringParam();
- param.setMissing(true);
- params.add(Patient.SP_FAMILY, param);
- List patients = toUnqualifiedVersionlessIds(myPatientDao.search(params));
- assertThat(patients).containsSubsequence(missing);
- assertThat(patients).doesNotContainSubsequence(notMissing);
- }
- }
-
- @Test
- public void testSearchWithToken() {
- IIdType notMissing;
- IIdType missing;
- {
- Observation obs = new Observation();
- obs.addIdentifier().setSystem("urn:system").setValue("001");
- missing = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
- }
- {
- Observation obs = new Observation();
- obs.addIdentifier().setSystem("urn:system").setValue("002");
- obs.getCode().addCoding().setSystem("urn:system").setCode("002");
- notMissing = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
- }
- // Token Param
- {
- SearchParameterMap params = new SearchParameterMap();
- params.setLoadSynchronous(true);
- TokenParam param = new TokenParam();
- param.setMissing(false);
- params.add(Observation.SP_CODE, param);
- List patients = toUnqualifiedVersionlessIds(myObservationDao.search(params));
- assertThat(patients).doesNotContainSubsequence(missing);
- assertThat(patients).containsSubsequence(notMissing);
- }
- {
- SearchParameterMap params = new SearchParameterMap();
- params.setLoadSynchronous(true);
- TokenParam param = new TokenParam();
- param.setMissing(true);
- params.add(Observation.SP_CODE, param);
- List patients = toUnqualifiedVersionlessIds(myObservationDao.search(params));
- assertThat(patients).containsSubsequence(missing);
- assertThat(patients).doesNotContainSubsequence(notMissing);
+ @Test
+ public void testSearchWithToken() {
+ IIdType notMissing;
+ IIdType missing;
+ {
+ Observation obs = new Observation();
+ obs.addIdentifier().setSystem("urn:system").setValue("001");
+ missing = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
+ }
+ {
+ Observation obs = new Observation();
+ obs.addIdentifier().setSystem("urn:system").setValue("002");
+ obs.getCode().addCoding().setSystem("urn:system").setCode("002");
+ notMissing = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
+ }
+ // Token Param
+ {
+ SearchParameterMap params = new SearchParameterMap();
+ params.setLoadSynchronous(true);
+ TokenParam param = new TokenParam();
+ param.setMissing(false);
+ params.add(Observation.SP_CODE, param);
+ List patients = toUnqualifiedVersionlessIds(myObservationDao.search(params, mySrd));
+ assertThat(patients).doesNotContainSubsequence(missing);
+ assertThat(patients).containsSubsequence(notMissing);
+ }
+ {
+ SearchParameterMap params = new SearchParameterMap();
+ params.setLoadSynchronous(true);
+ TokenParam param = new TokenParam();
+ param.setMissing(true);
+ params.add(Observation.SP_CODE, param);
+ List patients = toUnqualifiedVersionlessIds(myObservationDao.search(params, mySrd));
+ assertThat(patients).containsSubsequence(missing);
+ assertThat(patients).doesNotContainSubsequence(notMissing);
+ }
}
}
diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4Test.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4Test.java
index cb098dc7012..427970449c6 100644
--- a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4Test.java
+++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4Test.java
@@ -217,7 +217,7 @@ import static org.mockito.Mockito.when;
public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResourceProviderR4Test.class);
private SearchCoordinatorSvcImpl mySearchCoordinatorSvcRaw;
- private CapturingInterceptor myCapturingInterceptor = new CapturingInterceptor();
+ private final CapturingInterceptor myCapturingInterceptor = new CapturingInterceptor();
@Autowired
private ISearchDao mySearchEntityDao;
@@ -413,15 +413,15 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
Patient pt1 = new Patient();
pt1.addName().setFamily("Elizabeth");
- String pt1id = myPatientDao.create(pt1).getId().toUnqualifiedVersionless().getValue();
+ String pt1id = myPatientDao.create(pt1, mySrd).getId().toUnqualifiedVersionless().getValue();
Patient pt2 = new Patient();
pt2.addName().setFamily("fghijk");
- String pt2id = myPatientDao.create(pt2).getId().toUnqualifiedVersionless().getValue();
+ String pt2id = myPatientDao.create(pt2, mySrd).getId().toUnqualifiedVersionless().getValue();
Patient pt3 = new Patient();
pt3.addName().setFamily("zzzzz");
- myPatientDao.create(pt3).getId().toUnqualifiedVersionless().getValue();
+ myPatientDao.create(pt3, mySrd).getId().toUnqualifiedVersionless().getValue();
Bundle output = myClient
@@ -450,7 +450,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
Patient pt1 = new Patient();
pt1.addName().setFamily("Smith%");
- String pt1id = myPatientDao.create(pt1).getId().toUnqualifiedVersionless().getValue();
+ String pt1id = myPatientDao.create(pt1, mySrd).getId().toUnqualifiedVersionless().getValue();
Bundle output = myClient
.search()
@@ -463,7 +463,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
Patient pt2 = new Patient();
pt2.addName().setFamily("Sm%ith");
- String pt2id = myPatientDao.create(pt2).getId().toUnqualifiedVersionless().getValue();
+ String pt2id = myPatientDao.create(pt2, mySrd).getId().toUnqualifiedVersionless().getValue();
output = myClient
.search()
@@ -740,7 +740,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
Patient p = new Patient();
p.addName().setFamily("FAM").addGiven("GIV");
- IIdType id = myPatientDao.create(p).getId();
+ IIdType id = myPatientDao.create(p, mySrd).getId();
myClient.read().resource("Patient").withId(id.toUnqualifiedVersionless()).execute();
@@ -763,7 +763,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
Patient p = new Patient();
p.addName().setFamily("FAM").addGiven("GIV");
- IIdType id = myPatientDao.create(p).getId().toUnqualifiedVersionless();
+ IIdType id = myPatientDao.create(p, mySrd).getId().toUnqualifiedVersionless();
myClient
.delete()
@@ -1025,57 +1025,58 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
public void testCreateAndReadBackResourceWithContainedReferenceToContainer() {
myFhirContext.setParserErrorHandler(new StrictErrorHandler());
- String input = "{\n" +
- " \"resourceType\": \"Organization\",\n" +
- " \"id\": \"1\",\n" +
- " \"meta\": {\n" +
- " \"tag\": [\n" +
- " {\n" +
- " \"system\": \"https://blah.org/deployment\",\n" +
- " \"code\": \"e69414dd-b5c2-462d-bcfd-9d04d6b16596\",\n" +
- " \"display\": \"DEPLOYMENT\"\n" +
- " },\n" +
- " {\n" +
- " \"system\": \"https://blah.org/region\",\n" +
- " \"code\": \"b47d7a5b-b159-4bed-a8f8-3258e6603adb\",\n" +
- " \"display\": \"REGION\"\n" +
- " },\n" +
- " {\n" +
- " \"system\": \"https://blah.org/provider\",\n" +
- " \"code\": \"28c30004-0333-40cf-9e7f-3f9e080930bd\",\n" +
- " \"display\": \"PROVIDER\"\n" +
- " }\n" +
- " ]\n" +
- " },\n" +
- " \"contained\": [\n" +
- " {\n" +
- " \"resourceType\": \"Location\",\n" +
- " \"id\": \"2\",\n" +
- " \"position\": {\n" +
- " \"longitude\": 51.443238301454289,\n" +
- " \"latitude\": 7.34196905697293\n" +
- " },\n" +
- " \"managingOrganization\": {\n" +
- " \"reference\": \"#\"\n" +
- " }\n" +
- " }\n" +
- " ],\n" +
- " \"type\": [\n" +
- " {\n" +
- " \"coding\": [\n" +
- " {\n" +
- " \"system\": \"https://blah.org/fmc/OrganizationType\",\n" +
- " \"code\": \"CLINIC\",\n" +
- " \"display\": \"Clinic\"\n" +
- " }\n" +
- " ]\n" +
- " }\n" +
- " ],\n" +
- " \"name\": \"testOrg\"\n" +
- "}";
+ String input = """
+{
+ "resourceType": "Organization",
+ "id": "1",
+ "meta": {
+ "tag": [
+ {
+ "system": "https://blah.org/deployment",
+ "code": "e69414dd-b5c2-462d-bcfd-9d04d6b16596",
+ "display": "DEPLOYMENT"
+ },
+ {
+ "system": "https://blah.org/region",
+ "code": "b47d7a5b-b159-4bed-a8f8-3258e6603adb",
+ "display": "REGION"
+ },
+ {
+ "system": "https://blah.org/provider",
+ "code": "28c30004-0333-40cf-9e7f-3f9e080930bd",
+ "display": "PROVIDER"
+ }
+ ]
+ },
+ "contained": [
+ {
+ "resourceType": "Location",
+ "id": "2",
+ "position": {
+ "longitude": 51.443238301454289,
+ "latitude": 7.34196905697293
+ },
+ "managingOrganization": {
+ "reference": "#"
+ }
+ }
+ ],
+ "type": [
+ {
+ "coding": [
+ {
+ "system": "https://blah.org/fmc/OrganizationType",
+ "code": "CLINIC",
+ "display": "Clinic"
+ }
+ ]
+ }
+ ],
+ "name": "testOrg"
+}""";
Organization org = myFhirContext.newJsonParser().parseResource(Organization.class, input);
- IIdType id = myOrganizationDao.create(org).getId();
+ IIdType id = myOrganizationDao.create(org, mySrd).getId();
org = myOrganizationDao.read(id);
String output = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(org);
@@ -1095,9 +1096,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
}
List outcome = myClient.transaction().withResources(resources).prettyPrint().encodedXml().execute();
- runInTransaction(() -> {
- assertEquals(100, myResourceTableDao.count());
- });
+ runInTransaction(() -> assertEquals(100, myResourceTableDao.count()));
Bundle found = myClient
.search()
@@ -1306,7 +1305,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
}
@Test
- public void testCreateQuestionnaireResponseWithValidation() throws IOException {
+ public void testCreateQuestionnaireResponseWithValidation() {
CodeSystem cs = new CodeSystem();
cs.setUrl("http://cs");
cs.setStatus(Enumerations.PublicationStatus.ACTIVE);
@@ -1906,8 +1905,8 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
* Try it with a raw socket call. The Apache client won't let us use the unescaped "|" in the URL but we want to make sure that works too..
*/
Socket sock = new Socket();
- sock.setSoTimeout(3000);
- try {
+ try (sock) {
+ sock.setSoTimeout(3000);
sock.connect(new InetSocketAddress("localhost", myPort));
sock.getOutputStream().write(("DELETE /fhir/context/Patient?identifier=http://ghh.org/patient|" + methodName + " HTTP/1.1\n").getBytes(StandardCharsets.UTF_8));
sock.getOutputStream().write("Host: localhost\n".getBytes(StandardCharsets.UTF_8));
@@ -1915,7 +1914,6 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
BufferedReader socketInput = new BufferedReader(new InputStreamReader(sock.getInputStream()));
- // String response = "";
StringBuilder b = new StringBuilder();
char[] buf = new char[1000];
while (socketInput.read(buf) != -1) {
@@ -1925,9 +1923,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
ourLog.debug("Resp: {}", resp);
} catch (SocketTimeoutException e) {
- e.printStackTrace();
- } finally {
- sock.close();
+ ourLog.debug(e.getMessage(), e);
}
Thread.sleep(1000);
@@ -2398,7 +2394,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
assertThat(idValues).as(idValues.toString()).hasSize(10);
idValues = searchAndReturnUnqualifiedIdValues(myServerBase + "/_history?_at=gt" + InstantDt.withCurrentTime().getYear());
- assertThat(idValues).hasSize(0);
+ assertThat(idValues).isEmpty();
}
@@ -2427,7 +2423,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
myMemoryCacheService.invalidateCaches(MemoryCacheService.CacheEnum.PID_TO_FORCED_ID);
}
- Bundle history = myClient.history().onInstance(id.getValue()).andReturnBundle(Bundle.class).execute();
+ Bundle history = myClient.history().onInstance(id.getValue()).returnBundle(Bundle.class).execute();
assertEquals(1, history.getEntry().size());
BundleEntryComponent historyEntry0 = history.getEntry().get(0);
// validate entry.fullUrl
@@ -2476,7 +2472,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
myMemoryCacheService.invalidateCaches(MemoryCacheService.CacheEnum.PID_TO_FORCED_ID);
}
- Bundle history = myClient.history().onInstance(id.getValue()).andReturnBundle(Bundle.class).execute();
+ Bundle history = myClient.history().onInstance(id.getValue()).returnBundle(Bundle.class).execute();
assertEquals(1, history.getEntry().size());
BundleEntryComponent historyEntry0 = history.getEntry().get(0);
// validate entry.fullUrl
@@ -2508,7 +2504,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
ourLog.info("Res ID: {}", id);
- Bundle history = myClient.history().onInstance(id.getValue()).andReturnBundle(Bundle.class).prettyPrint().summaryMode(SummaryEnum.DATA).execute();
+ Bundle history = myClient.history().onInstance(id.getValue()).returnBundle(Bundle.class).prettyPrint().summaryMode(SummaryEnum.DATA).execute();
assertThat(history.getEntry()).hasSize(3);
assertEquals(id.withVersion("3").getValue(), history.getEntry().get(0).getResource().getId());
assertThat(((Patient) history.getEntry().get(0).getResource()).getName()).hasSize(1);
@@ -2746,7 +2742,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
int total = 20;
Organization org = new Organization();
org.setName("ORG");
- IIdType orgId = myOrganizationDao.create(org).getId().toUnqualifiedVersionless();
+ IIdType orgId = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless();
Coding tagCode = new Coding();
tagCode.setCode("test");
@@ -2757,7 +2753,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
.addTag(tagCode);
t.setStatus(Task.TaskStatus.REQUESTED);
t.getOwner().setReference(orgId.getValue());
- myTaskDao.create(t);
+ myTaskDao.create(t, mySrd);
}
HashSet ids = new HashSet<>();
@@ -2835,12 +2831,12 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
if (orgCount > 0) {
Organization org = new Organization();
org.setName("ORG");
- IIdType orgId = myOrganizationDao.create(org).getId().toUnqualifiedVersionless();
+ IIdType orgId = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless();
orgCount--;
t.getOwner().setReference(orgId.getValue());
}
- myTaskDao.create(t);
+ myTaskDao.create(t, mySrd);
}
}
@@ -2909,12 +2905,12 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
if (orgCount > 0) {
Organization org = new Organization();
org.setName("ORG");
- IIdType orgId = myOrganizationDao.create(org).getId().toUnqualifiedVersionless();
+ IIdType orgId = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless();
orgCount--;
t.getOwner().setReference(orgId.getValue());
}
- myTaskDao.create(t);
+ myTaskDao.create(t, mySrd);
}
}
@@ -2961,13 +2957,13 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
public void testIncludeCountDoesntIncludeIncludes() {
Organization org = new Organization();
org.setName("ORG");
- IIdType orgId = myOrganizationDao.create(org).getId().toUnqualifiedVersionless();
+ IIdType orgId = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless();
for (int i = 0; i < 10; i++) {
Patient pt = new Patient();
pt.getManagingOrganization().setReference(orgId.getValue());
pt.addName().setFamily("FAM" + i);
- myPatientDao.create(pt);
+ myPatientDao.create(pt, mySrd);
}
Bundle bundle = myClient
@@ -3168,7 +3164,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
Patient newPt = myClient.read().resource(Patient.class).withId(pid1.getIdPart()).execute();
assertEquals("2", newPt.getIdElement().getVersionIdPart());
- assertEquals(false, newPt.getActive());
+ assertFalse(newPt.getActive());
}
@Test
@@ -3196,7 +3192,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
Patient newPt = myClient.read().resource(Patient.class).withId(pid1.getIdPart()).execute();
assertEquals("1", newPt.getIdElement().getVersionIdPart());
- assertEquals(true, newPt.getActive());
+ assertTrue(newPt.getActive());
}
@Test
@@ -3226,7 +3222,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
Patient newPt = myClient.read().resource(Patient.class).withId(pid1.getIdPart()).execute();
assertEquals("2", newPt.getIdElement().getVersionIdPart());
- assertEquals(false, newPt.getActive());
+ assertFalse(newPt.getActive());
}
@Test
@@ -3255,7 +3251,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
Patient newPt = myClient.read().resource(Patient.class).withId(pid1.getIdPart()).execute();
assertEquals("2", newPt.getIdElement().getVersionIdPart());
- assertEquals(false, newPt.getActive());
+ assertFalse(newPt.getActive());
}
@Test
@@ -3323,12 +3319,12 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
{
Bundle returned = myClient.search().forResource(Patient.class).encodedXml().returnBundle(Bundle.class).execute();
- assertThat(returned.getEntry().size()).isGreaterThan(1);
+ assertThat(returned.getEntry()).hasSizeGreaterThan(1);
assertEquals(BundleType.SEARCHSET, returned.getType());
}
{
Bundle returned = myClient.search().forResource(Patient.class).encodedJson().returnBundle(Bundle.class).execute();
- assertThat(returned.getEntry().size()).isGreaterThan(1);
+ assertThat(returned.getEntry()).hasSizeGreaterThan(1);
}
}
@@ -3350,7 +3346,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
}
});
- Bundle bundle = myClient.history().onServer().andReturnBundle(Bundle.class).execute();
+ Bundle bundle = myClient.history().onServer().returnBundle(Bundle.class).execute();
assertEquals(1, bundle.getTotal());
assertThat(bundle.getEntry()).hasSize(1);
assertEquals(id2.getIdPart(), bundle.getEntry().get(0).getResource().getIdElement().getIdPart());
@@ -3507,15 +3503,6 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
assertThat(text).doesNotContain("\"B\"");
assertThat(text).doesNotContain("\"B1\"");
}
-
-
-// HttpGet read = new HttpGet(ourServerBase + "/Observation?patient=P5000000302&_sort:desc=code&code:in=http://fkcfhir.org/fhir/vs/ccdacapddialysisorder");
-// try (CloseableHttpResponse response = ourHttpClient.execute(read)) {
-// String text = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
-// ourLog.info(text);
-// assertEquals(Constants.STATUS_HTTP_200_OK, response.getStatusLine().getStatusCode());
-// assertThat(text).doesNotContain("\"text\",\"type\"");
-// }
}
@Test
@@ -3873,9 +3860,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
p.addName().setFamily(methodName + "1");
IIdType pid1 = myClient.create().resource(p).execute().getId().toUnqualifiedVersionless();
- Thread.sleep(10);
long time1 = System.currentTimeMillis();
- Thread.sleep(10);
Patient p2 = new Patient();
p2.addName().setFamily(methodName + "2");
@@ -4064,9 +4049,6 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
public void testSearchLastUpdatedParamRp() throws InterruptedException {
String methodName = "testSearchLastUpdatedParamRp";
- int sleep = 100;
- Thread.sleep(sleep);
-
DateTimeType beforeAny = new DateTimeType(new Date(), TemporalPrecisionEnum.MILLI);
IIdType id1a;
{
@@ -4083,9 +4065,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
id1b = myClient.create().resource(patient).execute().getId().toUnqualifiedVersionless();
}
- Thread.sleep(1100);
DateTimeType beforeR2 = new DateTimeType(new Date(), TemporalPrecisionEnum.MILLI);
- Thread.sleep(1100);
IIdType id2;
{
@@ -4249,13 +4229,12 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
Bundle bundle = myFhirContext.newXmlParser().parseResource(Bundle.class, resp);
matches = bundle.getEntry().size();
- assertThat(matches).isGreaterThan(0);
+ assertThat(matches).isPositive();
}
@Test
public void testSearchReturnsSearchDate() throws Exception {
Date before = new Date();
- Thread.sleep(1);
//@formatter:off
Bundle found = myClient
@@ -4266,7 +4245,6 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
.execute();
//@formatter:on
- Thread.sleep(1);
Date after = new Date();
InstantType updated = found.getMeta().getLastUpdatedElement();
@@ -4300,7 +4278,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
myObservationDao.create(obs, mySrd);
- ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
+ ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
{
@@ -4313,7 +4291,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
myObservationDao.create(obs, mySrd);
- ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
+ ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
{
@@ -4326,7 +4304,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
myObservationDao.create(obs, mySrd);
- ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
+ ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
{
@@ -4339,24 +4317,24 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
myObservationDao.create(obs, mySrd);
- ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
+ ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
// > 1m
String uri = myServerBase + "/Observation?code-value-quantity=http://" + UrlUtil.escapeUrlParam("loinc.org|2345-7$gt1|http://unitsofmeasure.org|m");
- ourLog.info("uri = " + uri);
+ ourLog.info("uri = {}", uri);
List ids = searchAndReturnUnqualifiedVersionlessIdValues(uri);
assertThat(ids).hasSize(3);
//>= 100cm
uri = myServerBase + "/Observation?code-value-quantity=http://" + UrlUtil.escapeUrlParam("loinc.org|2345-7$gt100|http://unitsofmeasure.org|cm");
- ourLog.info("uri = " + uri);
+ ourLog.info("uri = {}", uri);
ids = searchAndReturnUnqualifiedVersionlessIdValues(uri);
assertThat(ids).hasSize(3);
//>= 10dm
uri = myServerBase + "/Observation?code-value-quantity=http://" + UrlUtil.escapeUrlParam("loinc.org|2345-7$gt10|http://unitsofmeasure.org|dm");
- ourLog.info("uri = " + uri);
+ ourLog.info("uri = {}", uri);
ids = searchAndReturnUnqualifiedVersionlessIdValues(uri);
assertThat(ids).hasSize(3);
}
@@ -4381,7 +4359,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
myObservationDao.create(obs, mySrd);
- ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
+ ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
{
@@ -4392,7 +4370,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
myObservationDao.create(obs, mySrd);
- ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
+ ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
{
@@ -4403,7 +4381,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
myObservationDao.create(obs, mySrd);
- ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
+ ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
{
@@ -4414,7 +4392,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
myObservationDao.create(obs, mySrd);
- ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
+ ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
String uri;
@@ -4451,7 +4429,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
myObservationDao.create(obs, mySrd);
- ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
+ ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
{
@@ -4462,7 +4440,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
myObservationDao.create(obs, mySrd);
- ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
+ ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
{
@@ -4474,7 +4452,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
myObservationDao.create(obs, mySrd);
- ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
+ ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
myCaptureQueriesListener.clear();
@@ -4490,8 +4468,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
//-- check use normalized quantity table to search
String searchSql = myCaptureQueriesListener.getSelectQueries().get(0).getSql(true, true);
- assertThat(searchSql).doesNotContain("HFJ_SPIDX_QUANTITY t0");
- assertThat(searchSql).contains("HFJ_SPIDX_QUANTITY_NRML");
+ assertThat(searchSql).doesNotContain("HFJ_SPIDX_QUANTITY t0").contains("HFJ_SPIDX_QUANTITY_NRML");
}
@Test
@@ -5044,7 +5021,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
oid1 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
- ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
+ ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
{
@@ -5056,7 +5033,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
oid2 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
- ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
+ ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
{
@@ -5068,7 +5045,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
oid3 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
- ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
+ ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
{
@@ -5080,7 +5057,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
oid4 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
- ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
+ ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
String uri = myServerBase + "/Observation?_sort=code-value-quantity";
@@ -5092,7 +5069,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
found = myFhirContext.newXmlParser().parseResource(Bundle.class, output);
}
- ourLog.debug("Bundle: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(found));
+ ourLog.debug("Bundle: {}\n", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(found));
List list = toUnqualifiedVersionlessIds(found);
assertThat(found.getEntry()).hasSize(4);
@@ -5129,7 +5106,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
oid1 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
- ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
+ ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
{
@@ -5145,7 +5122,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
oid2 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
- ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
+ ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
{
@@ -5161,7 +5138,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
oid3 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
- ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
+ ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
{
@@ -5176,7 +5153,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
comp.setValue(new Quantity().setValue(250));
oid4 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
- ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
+ ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
String uri = myServerBase + "/Observation?_sort=combo-code-value-quantity";
@@ -5188,7 +5165,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
found = myFhirContext.newXmlParser().parseResource(Bundle.class, output);
}
- ourLog.debug("Bundle: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(found));
+ ourLog.debug("Bundle: {}\n", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(found));
List list = toUnqualifiedVersionlessIds(found);
assertThat(found.getEntry()).hasSize(4);
@@ -5264,9 +5241,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
List list = toUnqualifiedVersionlessIds(found);
ourLog.info(methodName + " found: " + list.toString() + " - Wanted " + orgMissing + " but not " + orgNotMissing);
- assertThat(list).doesNotContain(orgNotMissing);
- assertThat(list).doesNotContain(deletedIdMissingTrue);
- assertThat(list).contains(orgMissing);
+ assertThat(list).doesNotContain(orgNotMissing).doesNotContain(deletedIdMissingTrue).contains(orgMissing);
}
@Test
@@ -5927,7 +5902,6 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
}
Date before = new Date();
- Thread.sleep(100);
pt = new Patient();
pt.setId(id.getIdPart());
@@ -6450,7 +6424,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
cc.addCoding().setCode("2345-7").setSystem("http://loinc.org");
obs.setValue(new Quantity().setValueElement(new DecimalType(125.12)).setUnit("CM").setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL).setCode("cm"));
- ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
+ ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
IIdType opid1 = myObservationDao.create(obs, mySrd).getId();
@@ -6463,7 +6437,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
cc.addCoding().setCode("2345-7").setSystem("http://loinc.org");
obs.setValue(new Quantity().setValueElement(new DecimalType(24.12)).setUnit("CM").setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL).setCode("cm"));
- ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
+ ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
myObservationDao.update(obs, mySrd);
}
@@ -6479,7 +6453,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
myObservationDao.create(obs, mySrd);
- ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
+ ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
{
@@ -6492,7 +6466,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
myObservationDao.create(obs, mySrd);
- ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
+ ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
{
@@ -6505,25 +6479,25 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
myObservationDao.create(obs, mySrd);
- ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
+ ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
// > 1m
String uri = myServerBase + "/Observation?code-value-quantity=http://" + UrlUtil.escapeUrlParam("loinc.org|2345-7$gt1|http://unitsofmeasure.org|m");
- ourLog.info("uri = " + uri);
+ ourLog.info("uri = {}", uri);
List ids = searchAndReturnUnqualifiedVersionlessIdValues(uri);
assertThat(ids).hasSize(2);
//>= 100cm
uri = myServerBase + "/Observation?code-value-quantity=http://" + UrlUtil.escapeUrlParam("loinc.org|2345-7$gt100|http://unitsofmeasure.org|cm");
- ourLog.info("uri = " + uri);
+ ourLog.info("uri = {}", uri);
ids = searchAndReturnUnqualifiedVersionlessIdValues(uri);
assertThat(ids).hasSize(2);
//>= 10dm
uri = myServerBase + "/Observation?code-value-quantity=http://" + UrlUtil.escapeUrlParam("loinc.org|2345-7$gt10|http://unitsofmeasure.org|dm");
- ourLog.info("uri = " + uri);
+ ourLog.info("uri = {}", uri);
ids = searchAndReturnUnqualifiedVersionlessIdValues(uri);
assertThat(ids).hasSize(2);
}
@@ -6540,7 +6514,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
patient.setBirthDateElement(new DateType("2073"));
pid0 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
- ourLog.debug("Patient: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(patient));
+ ourLog.debug("Patient: {}\n", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(patient));
ourLog.info("pid0 " + pid0);
}
@@ -6553,7 +6527,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
String resp = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
ourLog.info(resp);
Bundle bundle = myFhirContext.newXmlParser().parseResource(Bundle.class, resp);
- ourLog.debug("Patient: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(bundle));
+ ourLog.debug("Patient: {}\n", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(bundle));
}
uri = myServerBase + "/Patient?_total=accurate&birthdate=gt2072-01-01";
@@ -6564,7 +6538,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
String resp = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
ourLog.info(resp);
Bundle bundle = myFhirContext.newXmlParser().parseResource(Bundle.class, resp);
- ourLog.debug("Patient: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(bundle));
+ ourLog.debug("Patient: {}\n", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(bundle));
}
}
@@ -6995,9 +6969,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
&& theInput.IsEnforceRefOnType
&& theInput.IsEnforceRefOnWrite).isFalse();
} catch (InvalidRequestException ex) {
- assertThat(ex.getMessage().contains(
- "Invalid resource reference"
- )).as(ex.getMessage()).isTrue();
+ assertThat(ex.getMessage()).as(ex.getMessage()).contains("Invalid resource reference");
} finally {
myStorageSettings.setEnforceReferentialIntegrityOnWrite(isEnforceRefOnWrite);
myStorageSettings.setEnforceReferenceTargetTypes(isEnforceRefTargetTypes);
@@ -7331,9 +7303,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
patient.setBirthDate(cal.getTime());
}
return patient;
- }, (isMissing) -> {
- return doSearch(Patient.class, Patient.BIRTHDATE.isMissing(isMissing));
- });
+ }, (isMissing) -> doSearch(Patient.class, Patient.BIRTHDATE.isMissing(isMissing)));
}
@ParameterizedTest
@@ -7346,9 +7316,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
patient.setGender(AdministrativeGender.FEMALE);
}
return patient;
- }, isMissing -> {
- return doSearch(Patient.class, Patient.GENDER.isMissing(isMissing));
- });
+ }, isMissing -> doSearch(Patient.class, Patient.GENDER.isMissing(isMissing)));
}
@ParameterizedTest
@@ -7364,9 +7332,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
patient.setGeneralPractitioner(Collections.singletonList(new Reference(practitionerId)));
}
return patient;
- }, isMissing -> {
- return doSearch(Patient.class, Patient.GENERAL_PRACTITIONER.isMissing(isMissing));
- });
+ }, isMissing -> doSearch(Patient.class, Patient.GENERAL_PRACTITIONER.isMissing(isMissing)));
}
@ParameterizedTest
@@ -7409,9 +7375,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
sp.setUrl("http://example.com");
}
return sp;
- }, isMissing -> {
- return doSearch(SearchParameter.class, SearchParameter.URL.isMissing(isMissing));
- });
+ }, isMissing -> doSearch(SearchParameter.class, SearchParameter.URL.isMissing(isMissing)));
}
@ParameterizedTest
@@ -7424,9 +7388,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
obs.setValue(new Quantity(3));
}
return obs;
- }, isMissing -> {
- return doSearch(Observation.class, Observation.VALUE_QUANTITY.isMissing(isMissing));
- });
+ }, isMissing -> doSearch(Observation.class, Observation.VALUE_QUANTITY.isMissing(isMissing)));
}
@ParameterizedTest
@@ -7457,7 +7419,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
Y doTask(X theInput);
}
- private static class MissingSearchTestParameters {
+ public static class MissingSearchTestParameters {
/**
* The setting for IndexMissingFields
*/
diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/term/TerminologySvcImplCurrentVersionR4Test.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/term/TerminologySvcImplCurrentVersionR4Test.java
index 3eb62d47179..11d7cb3b767 100644
--- a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/term/TerminologySvcImplCurrentVersionR4Test.java
+++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/term/TerminologySvcImplCurrentVersionR4Test.java
@@ -1,9 +1,8 @@
package ca.uhn.fhir.jpa.term;
-import static org.junit.jupiter.api.Assertions.assertNull;
import ca.uhn.fhir.context.support.IValidationSupport;
-import ca.uhn.fhir.context.support.ValidationSupportContext;
import ca.uhn.fhir.context.support.LookupCodeRequest;
+import ca.uhn.fhir.context.support.ValidationSupportContext;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.config.JpaConfig;
import ca.uhn.fhir.jpa.entity.TermCodeSystem;
@@ -20,9 +19,10 @@ import ca.uhn.fhir.rest.param.UriParam;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
+import jakarta.persistence.EntityManager;
+import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.instance.model.api.IBaseResource;
-import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.CodeSystem;
import org.hl7.fhir.r4.model.CodeType;
import org.hl7.fhir.r4.model.IdType;
@@ -40,8 +40,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.io.ClassPathResource;
-import jakarta.persistence.EntityManager;
-import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
@@ -82,14 +80,12 @@ import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_UPLOAD_
import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_XML_FILE;
import static java.util.stream.Collectors.joining;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.Assertions.fail;
import static org.hl7.fhir.common.hapi.validation.support.ValidationConstants.LOINC_ALL_VALUESET_ID;
import static org.hl7.fhir.common.hapi.validation.support.ValidationConstants.LOINC_LOW;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.fail;
-
import static org.mockito.Mockito.when;
/**
@@ -141,9 +137,7 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
@Autowired
private Batch2JobHelper myBatchJobHelper;
-
- private ZipCollectionBuilder myFiles;
- private ServletRequestDetails myRequestDetails = new ServletRequestDetails();
+ private final ServletRequestDetails myRequestDetails = new ServletRequestDetails();
private Properties uploadProperties;
private IFhirResourceDao myValueSetIFhirResourceDao;
@@ -182,17 +176,7 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
private void validateValidateCode(String theCurrentVersion, Collection allVersions) {
- IValidationSupport.CodeValidationResult resultNoVersioned = myCodeSystemDao.validateCode(null,
- new UriType(BASE_LOINC_URL), null, new CodeType(VS_NO_VERSIONED_ON_UPLOAD_FIRST_CODE),
- null, null, null, null);
- assertNotNull(resultNoVersioned);
- assertEquals(prefixWithVersion(theCurrentVersion, VS_NO_VERSIONED_ON_UPLOAD_FIRST_DISPLAY), resultNoVersioned.getDisplay());
-
- IValidationSupport.CodeValidationResult resultVersioned = myCodeSystemDao.validateCode(null,
- new UriType(BASE_LOINC_URL), null, new CodeType(VS_VERSIONED_ON_UPLOAD_FIRST_CODE),
- null, null, null, null);
- assertNotNull(resultVersioned);
- assertEquals(prefixWithVersion(theCurrentVersion, VS_VERSIONED_ON_UPLOAD_FIRST_DISPLAY), resultVersioned.getDisplay());
+ validateValidateCodeForVersion(theCurrentVersion);
allVersions.forEach(this::validateValidateCodeForVersion);
}
@@ -215,13 +199,15 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
private void validateValueLookup(String theCurrentVersion, Collection allVersions) {
IValidationSupport.LookupCodeResult resultNoVer = myValidationSupport.lookupCode(
- new ValidationSupportContext(myValidationSupport), new LookupCodeRequest(BASE_LOINC_URL, VS_NO_VERSIONED_ON_UPLOAD_FIRST_CODE));
+ new ValidationSupportContext(myValidationSupport),
+ new LookupCodeRequest(BASE_LOINC_URL, VS_NO_VERSIONED_ON_UPLOAD_FIRST_CODE));
assertNotNull(resultNoVer);
String expectedNoVer = prefixWithVersion(theCurrentVersion, VS_NO_VERSIONED_ON_UPLOAD_FIRST_DISPLAY);
assertEquals(expectedNoVer, resultNoVer.getCodeDisplay());
IValidationSupport.LookupCodeResult resultWithVer = myValidationSupport.lookupCode(
- new ValidationSupportContext(myValidationSupport), new LookupCodeRequest(BASE_LOINC_URL, VS_VERSIONED_ON_UPLOAD_FIRST_CODE));
+ new ValidationSupportContext(myValidationSupport),
+ new LookupCodeRequest(BASE_LOINC_URL, VS_VERSIONED_ON_UPLOAD_FIRST_CODE));
assertNotNull(resultWithVer);
String expectedWithVer = prefixWithVersion(theCurrentVersion, VS_VERSIONED_ON_UPLOAD_FIRST_DISPLAY);
assertEquals(expectedWithVer, resultWithVer.getCodeDisplay());
@@ -278,42 +264,28 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
private void validateExpandedTermConcepts(String theCurrentVersion, Collection theAllVersions) {
runInTransaction(() -> {
- TermConcept termConceptNoVerCsvNoVer = (TermConcept) myEntityManager.createQuery(
- "select tc from TermConcept tc join fetch tc.myCodeSystem tcsv where tc.myCode = '" +
- VS_NO_VERSIONED_ON_UPLOAD_FIRST_CODE + "' and tcsv.myCodeSystemVersionId is null").getSingleResult();
- assertNotNull(termConceptNoVerCsvNoVer);
- // data should have version because it was loaded with a version
- assertEquals(prefixWithVersion(theCurrentVersion, VS_NO_VERSIONED_ON_UPLOAD_FIRST_DISPLAY), termConceptNoVerCsvNoVer.getDisplay());
-
- TermConcept termConceptVerCsvNoVer = (TermConcept) myEntityManager.createQuery(
- "select tc from TermConcept tc join fetch tc.myCodeSystem tcsv where tc.myCode = '" +
- VS_VERSIONED_ON_UPLOAD_FIRST_CODE + "' and tcsv.myCodeSystemVersionId is null").getSingleResult();
- assertNotNull(termConceptVerCsvNoVer);
- // data should have version because it was loaded with a version
- assertEquals(prefixWithVersion(theCurrentVersion, VS_VERSIONED_ON_UPLOAD_FIRST_DISPLAY), termConceptVerCsvNoVer.getDisplay());
-
- if (theCurrentVersion != null) {
- TermConcept termConceptNoVerCsvVer = (TermConcept) myEntityManager.createQuery(
+ TermConcept termConceptNoVerCsvNoVer = (TermConcept) myEntityManager.createQuery(
"select tc from TermConcept tc join fetch tc.myCodeSystem tcsv where tc.myCode = '" +
- VS_NO_VERSIONED_ON_UPLOAD_FIRST_CODE + "' and tcsv.myCodeSystemVersionId = '" + theCurrentVersion + "'").getSingleResult();
- assertNotNull(termConceptNoVerCsvVer);
+ VS_NO_VERSIONED_ON_UPLOAD_FIRST_CODE + "' and tcsv.myCodeSystemVersionId is null").getSingleResult();
+ assertNotNull(termConceptNoVerCsvNoVer);
// data should have version because it was loaded with a version
- assertEquals(prefixWithVersion(theCurrentVersion, VS_NO_VERSIONED_ON_UPLOAD_FIRST_DISPLAY), termConceptNoVerCsvVer.getDisplay());
+ assertEquals(prefixWithVersion(theCurrentVersion, VS_NO_VERSIONED_ON_UPLOAD_FIRST_DISPLAY), termConceptNoVerCsvNoVer.getDisplay());
- TermConcept termConceptVerCsvVer = (TermConcept) myEntityManager.createQuery(
+ TermConcept termConceptVerCsvNoVer = (TermConcept) myEntityManager.createQuery(
"select tc from TermConcept tc join fetch tc.myCodeSystem tcsv where tc.myCode = '" +
- VS_VERSIONED_ON_UPLOAD_FIRST_CODE + "' and tcsv.myCodeSystemVersionId = '" + theCurrentVersion + "'").getSingleResult();
- assertNotNull(termConceptVerCsvVer);
+ VS_VERSIONED_ON_UPLOAD_FIRST_CODE + "' and tcsv.myCodeSystemVersionId is null").getSingleResult();
+ assertNotNull(termConceptVerCsvNoVer);
// data should have version because it was loaded with a version
- assertEquals(prefixWithVersion(theCurrentVersion, VS_VERSIONED_ON_UPLOAD_FIRST_DISPLAY), termConceptVerCsvVer.getDisplay());
- }
+ assertEquals(prefixWithVersion(theCurrentVersion, VS_VERSIONED_ON_UPLOAD_FIRST_DISPLAY), termConceptVerCsvNoVer.getDisplay());
- theAllVersions.forEach(this::validateExpandedTermConceptsForVersion);
+ if (theCurrentVersion != null) {
+ validateExpandedTermConceptsForVersion(theCurrentVersion);
+ }
+ theAllVersions.forEach(this::validateExpandedTermConceptsForVersion);
});
}
-
private void validateExpandedTermConceptsForVersion(String theVersion) {
TermConcept termConceptNoVer = (TermConcept) myEntityManager.createQuery(
"select tc from TermConcept tc join fetch tc.myCodeSystem tcsv where tc.myCode = '" +
@@ -384,7 +356,7 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
* no the CodeSystem version.
*/
private void validateValueSetSearchForVersion(String theVersion) {
- // for no versioned VS (VS version, different than CS version)
+ // for no versioned VS (VS version, different from CS version)
SearchParameterMap paramsUploadNoVer = new SearchParameterMap("url", new UriParam(VS_NO_VERSIONED_ON_UPLOAD));
paramsUploadNoVer.add("version", new TokenParam(theVersion));
@@ -398,7 +370,7 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
assertEquals(expectedLoadNoVersionUnqualifiedId, loadNoVersionValueSet.getIdElement().getIdPart());
- // versioned VS (VS version, different than CS version)
+ // versioned VS (VS version, different from CS version)
SearchParameterMap paramsUploadVer = new SearchParameterMap("url", new UriParam(VS_VERSIONED_ON_UPLOAD));
paramsUploadVer.add("version", new TokenParam(VS_ANSWER_LIST_VERSION + "-" + theVersion));
@@ -437,8 +409,8 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
Set theExpectedIdVersionsPlusNull = Sets.newHashSet(theExpectedIdVersions);
theExpectedIdVersionsPlusNull.add(null);
- assertThat(theExpectedIdVersionsPlusNull).containsExactlyInAnyOrderElementsOf(theValueSets.stream().map(r -> ((ValueSet) r).getVersion()).toList());
-
+ List valueSetVersions = theValueSets.stream().map(r -> ((ValueSet) r).getVersion()).toList();
+ assertThat(valueSetVersions).containsExactlyInAnyOrderElementsOf(theExpectedIdVersionsPlusNull);
}
@@ -455,14 +427,13 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
// for CodeSystem:
// _ current CS is present and has no version
- CodeSystem codeSystem = myCodeSystemDao.read(new IdType(LOINC_LOW));
+ CodeSystem codeSystem = myCodeSystemDao.read(new IdType(LOINC_LOW), myRequestDetails);
String csString = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(codeSystem);
- ourLog.info("CodeSystem:\n" + csString);
+ ourLog.info("CodeSystem:\n {}", csString);
HashSet shouldNotBePresentVersions = new HashSet<>(possibleVersions);
theAllVersions.forEach(shouldNotBePresentVersions::remove);
- shouldNotBePresentVersions.forEach(vv -> assertFalse(csString.contains(vv),
- "Found version string: '" + vv + "' in CodeSystem: " + csString));
+ assertThat(shouldNotBePresentVersions).noneSatisfy(vv -> assertThat(vv).isEqualTo(codeSystem.getVersion()));
// same reading it from term service
CodeSystem cs = myITermReadSvc.fetchCanonicalCodeSystemFromCompleteContext(BASE_LOINC_URL);
@@ -501,7 +472,7 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
@Test()
public void uploadCurrentNoVersion() throws Exception {
- IIdType csId = uploadLoincCodeSystem(null, true);
+ uploadLoincCodeSystem(null, true);
runCommonValidations(Collections.emptyList());
@@ -516,7 +487,7 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
@Test()
public void uploadWithVersion() throws Exception {
String ver = "2.67";
- IIdType csId = uploadLoincCodeSystem(ver, true);
+ uploadLoincCodeSystem(ver, true);
runCommonValidations(Collections.singletonList(ver));
@@ -637,25 +608,6 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
assertThat(vsContainsDisplay).contains(expectedDisplay);
}
-
- private void validateValidateCodeLoincAllVS(String theCurrentVersion, Collection allVersions) {
- IValidationSupport.CodeValidationResult resultNoVersioned = myCodeSystemDao.validateCode(null,
- new UriType(BASE_LOINC_URL), null, new CodeType(VS_NO_VERSIONED_ON_UPLOAD_FIRST_CODE),
- null, null, null, null);
- assertNotNull(resultNoVersioned);
- assertEquals(prefixWithVersion(theCurrentVersion, VS_NO_VERSIONED_ON_UPLOAD_FIRST_DISPLAY), resultNoVersioned.getDisplay());
-
- IValidationSupport.CodeValidationResult resultVersioned = myCodeSystemDao.validateCode(null,
- new UriType(BASE_LOINC_URL), null, new CodeType(VS_VERSIONED_ON_UPLOAD_FIRST_CODE),
- null, null, null, null);
- assertNotNull(resultVersioned);
- assertEquals(prefixWithVersion(theCurrentVersion, VS_VERSIONED_ON_UPLOAD_FIRST_DISPLAY), resultVersioned.getDisplay());
-
- allVersions.forEach(this::validateValidateCodeForVersion);
- }
-
-
-
private void validateValueExpandLoincAllVsForVersion(String theVersion) {
ValueSet vs = myValueSetDao.expandByIdentifier(LOINC_ALL_VS_URL + "|" + theVersion, null);
assertThat(vs.getExpansion().getContains()).hasSize(ALL_VS_QTY);
@@ -664,7 +616,6 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
checkContainsElementVersion(vs, theVersion);
}
-
/**
* Validates TermConcepts were created in the sequence indicated by the parameters
* and their displays match the expected versions
@@ -735,8 +686,8 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
}
- private IIdType uploadLoincCodeSystem(String theVersion, boolean theMakeItCurrent) throws Exception {
- myFiles = new ZipCollectionBuilder();
+ private void uploadLoincCodeSystem(String theVersion, boolean theMakeItCurrent) throws Exception {
+ ZipCollectionBuilder files = new ZipCollectionBuilder();
myRequestDetails.getUserData().put(LOINC_CODESYSTEM_MAKE_CURRENT, theMakeItCurrent);
uploadProperties.put(LOINC_CODESYSTEM_MAKE_CURRENT.getCode(), Boolean.toString(theMakeItCurrent));
@@ -749,12 +700,10 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
uploadProperties.put(LOINC_CODESYSTEM_VERSION.getCode(), theVersion);
}
- addLoincMandatoryFilesToZip(myFiles, theVersion);
+ addLoincMandatoryFilesToZip(files, theVersion);
- UploadStatistics stats = myTermLoaderSvc.loadLoinc(myFiles.getFiles(), mySrd);
+ myTermLoaderSvc.loadLoinc(files.getFiles(), mySrd);
myTerminologyDeferredStorageSvc.saveAllDeferred();
-
- return stats.getTarget();
}
@@ -787,10 +736,12 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
private TermCodeSystemVersion fetchCurrentCodeSystemVersion() {
runInTransaction(() -> {
+ @SuppressWarnings("unchecked")
List tcsList = myEntityManager.createQuery("from TermCodeSystem").getResultList();
+ @SuppressWarnings("unchecked")
List tcsvList = myEntityManager.createQuery("from TermCodeSystemVersion").getResultList();
- ourLog.error("tcslist: {}", tcsList.stream().map(tcs -> tcs.toString()).collect(joining("\n", "\n", "")));
- ourLog.error("tcsvlist: {}", tcsvList.stream().map(v -> v.toString()).collect(joining("\n", "\n", "")));
+ ourLog.error("tcslist: {}", tcsList.stream().map(TermCodeSystem::toString).collect(joining("\n", "\n", "")));
+ ourLog.error("tcsvlist: {}", tcsvList.stream().map(TermCodeSystemVersion::toString).collect(joining("\n", "\n", "")));
if (tcsList.size() != 1) {
throw new IllegalStateException("More than one TCS: " +
@@ -807,8 +758,9 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
}
- private static void addBaseLoincMandatoryFilesToZip(
- ZipCollectionBuilder theFiles, Boolean theIncludeTop2000, String theClassPathPrefix) throws IOException {
+ private static void addBaseLoincMandatoryFilesToZip(ZipCollectionBuilder theFiles,
+ @SuppressWarnings("SameParameterValue") Boolean theIncludeTop2000,
+ String theClassPathPrefix) throws IOException {
theFiles.addFileZip(theClassPathPrefix, LOINC_XML_FILE.getCode());
theFiles.addFileZip(theClassPathPrefix, LOINC_GROUP_FILE_DEFAULT.getCode());
theFiles.addFileZip(theClassPathPrefix, LOINC_GROUP_TERMS_FILE_DEFAULT.getCode());
diff --git a/hapi-fhir-jpaserver-test-r4b/pom.xml b/hapi-fhir-jpaserver-test-r4b/pom.xml
index 37dad0b5380..dec34cddda1 100644
--- a/hapi-fhir-jpaserver-test-r4b/pom.xml
+++ b/hapi-fhir-jpaserver-test-r4b/pom.xml
@@ -6,7 +6,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-test-r5/pom.xml b/hapi-fhir-jpaserver-test-r5/pom.xml
index 9922a18d6d9..32b02b3e1ad 100644
--- a/hapi-fhir-jpaserver-test-r5/pom.xml
+++ b/hapi-fhir-jpaserver-test-r5/pom.xml
@@ -6,7 +6,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-test-utilities/pom.xml b/hapi-fhir-jpaserver-test-utilities/pom.xml
index 61c593d03cf..71e63e55591 100644
--- a/hapi-fhir-jpaserver-test-utilities/pom.xml
+++ b/hapi-fhir-jpaserver-test-utilities/pom.xml
@@ -6,7 +6,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-uhnfhirtest/pom.xml b/hapi-fhir-jpaserver-uhnfhirtest/pom.xml
index 47dd4ef075c..f62519f252c 100644
--- a/hapi-fhir-jpaserver-uhnfhirtest/pom.xml
+++ b/hapi-fhir-jpaserver-uhnfhirtest/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../pom.xml
diff --git a/hapi-fhir-server-cds-hooks/pom.xml b/hapi-fhir-server-cds-hooks/pom.xml
index 5f52f9cdf23..1f396dc4fdc 100644
--- a/hapi-fhir-server-cds-hooks/pom.xml
+++ b/hapi-fhir-server-cds-hooks/pom.xml
@@ -7,7 +7,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-server-cds-hooks/src/main/java/ca/uhn/hapi/fhir/cdshooks/api/ICdsServiceRegistry.java b/hapi-fhir-server-cds-hooks/src/main/java/ca/uhn/hapi/fhir/cdshooks/api/ICdsServiceRegistry.java
index e385650dc25..e3002797b60 100644
--- a/hapi-fhir-server-cds-hooks/src/main/java/ca/uhn/hapi/fhir/cdshooks/api/ICdsServiceRegistry.java
+++ b/hapi-fhir-server-cds-hooks/src/main/java/ca/uhn/hapi/fhir/cdshooks/api/ICdsServiceRegistry.java
@@ -45,7 +45,7 @@ public interface ICdsServiceRegistry {
* @param theCdsServiceRequestJson the service request
* @return the service response
*/
- CdsServiceResponseJson callService(String theServiceId, CdsServiceRequestJson theCdsServiceRequestJson);
+ CdsServiceResponseJson callService(String theServiceId, Object theCdsServiceRequestJson);
/**
* This is the REST method available at https://example.com/cds-services/{theServiceId}/feedback
diff --git a/hapi-fhir-server-cds-hooks/src/main/java/ca/uhn/hapi/fhir/cdshooks/api/json/CdsHooksExtension.java b/hapi-fhir-server-cds-hooks/src/main/java/ca/uhn/hapi/fhir/cdshooks/api/json/CdsHooksExtension.java
index adfbf119e5d..f4d41bc2189 100644
--- a/hapi-fhir-server-cds-hooks/src/main/java/ca/uhn/hapi/fhir/cdshooks/api/json/CdsHooksExtension.java
+++ b/hapi-fhir-server-cds-hooks/src/main/java/ca/uhn/hapi/fhir/cdshooks/api/json/CdsHooksExtension.java
@@ -20,9 +20,11 @@
package ca.uhn.hapi.fhir.cdshooks.api.json;
import ca.uhn.fhir.model.api.IModelJson;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
/**
* Users can define CDS Hooks extensions by extending this class.
* Implementors can extend this class for defining their custom extensions.
*/
+@JsonIgnoreProperties(ignoreUnknown = true)
public class CdsHooksExtension implements IModelJson {}
diff --git a/hapi-fhir-server-cds-hooks/src/main/java/ca/uhn/hapi/fhir/cdshooks/api/json/CdsServiceRequestContextJson.java b/hapi-fhir-server-cds-hooks/src/main/java/ca/uhn/hapi/fhir/cdshooks/api/json/CdsServiceRequestContextJson.java
index de2988594c7..9fb8649e5ee 100644
--- a/hapi-fhir-server-cds-hooks/src/main/java/ca/uhn/hapi/fhir/cdshooks/api/json/CdsServiceRequestContextJson.java
+++ b/hapi-fhir-server-cds-hooks/src/main/java/ca/uhn/hapi/fhir/cdshooks/api/json/CdsServiceRequestContextJson.java
@@ -21,6 +21,7 @@ package ca.uhn.hapi.fhir.cdshooks.api.json;
import ca.uhn.fhir.model.api.IModelJson;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import org.hl7.fhir.instance.model.api.IBaseResource;
import java.util.Collections;
@@ -29,6 +30,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
+@JsonIgnoreProperties(ignoreUnknown = true)
public class CdsServiceRequestContextJson extends BaseCdsServiceJson implements IModelJson {
@JsonAnyGetter
diff --git a/hapi-fhir-server-cds-hooks/src/main/java/ca/uhn/hapi/fhir/cdshooks/config/CdsHooksConfig.java b/hapi-fhir-server-cds-hooks/src/main/java/ca/uhn/hapi/fhir/cdshooks/config/CdsHooksConfig.java
index 37efd73711c..34f9b2258ab 100644
--- a/hapi-fhir-server-cds-hooks/src/main/java/ca/uhn/hapi/fhir/cdshooks/config/CdsHooksConfig.java
+++ b/hapi-fhir-server-cds-hooks/src/main/java/ca/uhn/hapi/fhir/cdshooks/config/CdsHooksConfig.java
@@ -31,6 +31,7 @@ import ca.uhn.hapi.fhir.cdshooks.api.ICdsConfigService;
import ca.uhn.hapi.fhir.cdshooks.api.ICdsHooksDaoAuthorizationSvc;
import ca.uhn.hapi.fhir.cdshooks.api.ICdsServiceRegistry;
import ca.uhn.hapi.fhir.cdshooks.module.CdsHooksObjectMapperFactory;
+import ca.uhn.hapi.fhir.cdshooks.serializer.CdsServiceRequestJsonDeserializer;
import ca.uhn.hapi.fhir.cdshooks.svc.CdsConfigServiceImpl;
import ca.uhn.hapi.fhir.cdshooks.svc.CdsHooksContextBooter;
import ca.uhn.hapi.fhir.cdshooks.svc.CdsServiceRegistryImpl;
@@ -100,13 +101,15 @@ public class CdsHooksConfig {
ICdsCrServiceFactory theCdsCrServiceFactory,
ICrDiscoveryServiceFactory theCrDiscoveryServiceFactory,
FhirContext theFhirContext) {
+ final CdsServiceRequestJsonDeserializer cdsServiceRequestJsonDeserializer =
+ new CdsServiceRequestJsonDeserializer(theFhirContext, theObjectMapper);
return new CdsServiceRegistryImpl(
theCdsHooksContextBooter,
theCdsPrefetchSvc,
theObjectMapper,
theCdsCrServiceFactory,
theCrDiscoveryServiceFactory,
- theFhirContext);
+ cdsServiceRequestJsonDeserializer);
}
@Bean
diff --git a/hapi-fhir-server-cds-hooks/src/main/java/ca/uhn/hapi/fhir/cdshooks/controller/CdsHooksController.java b/hapi-fhir-server-cds-hooks/src/main/java/ca/uhn/hapi/fhir/cdshooks/controller/CdsHooksController.java
index 10896e2f74a..0ae202abec4 100644
--- a/hapi-fhir-server-cds-hooks/src/main/java/ca/uhn/hapi/fhir/cdshooks/controller/CdsHooksController.java
+++ b/hapi-fhir-server-cds-hooks/src/main/java/ca/uhn/hapi/fhir/cdshooks/controller/CdsHooksController.java
@@ -21,7 +21,6 @@ package ca.uhn.hapi.fhir.cdshooks.controller;
import ca.uhn.hapi.fhir.cdshooks.api.ICdsServiceRegistry;
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceFeedbackJson;
-import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceRequestJson;
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceResponseJson;
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServicesJson;
import org.springframework.http.HttpStatus;
@@ -73,7 +72,7 @@ public class CdsHooksController {
method = {RequestMethod.POST},
consumes = {MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity cdsServiceRequest(
- @PathVariable("cds_hook") String theCdsHook, @RequestBody CdsServiceRequestJson theCdsServiceRequestJson) {
+ @PathVariable("cds_hook") String theCdsHook, @RequestBody Object theCdsServiceRequestJson) {
CdsServiceResponseJson response = myCdsServiceRegistry.callService(theCdsHook, theCdsServiceRequestJson);
return ResponseEntity.status(200)
.contentType(MediaType.APPLICATION_JSON)
diff --git a/hapi-fhir-server-cds-hooks/src/main/java/ca/uhn/hapi/fhir/cdshooks/serializer/CdsServiceRequestJsonDeserializer.java b/hapi-fhir-server-cds-hooks/src/main/java/ca/uhn/hapi/fhir/cdshooks/serializer/CdsServiceRequestJsonDeserializer.java
index 6019a3d114c..d64ff9c3964 100644
--- a/hapi-fhir-server-cds-hooks/src/main/java/ca/uhn/hapi/fhir/cdshooks/serializer/CdsServiceRequestJsonDeserializer.java
+++ b/hapi-fhir-server-cds-hooks/src/main/java/ca/uhn/hapi/fhir/cdshooks/serializer/CdsServiceRequestJsonDeserializer.java
@@ -20,84 +20,60 @@
package ca.uhn.hapi.fhir.cdshooks.serializer;
import ca.uhn.fhir.context.FhirContext;
+import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.parser.IParser;
-import ca.uhn.fhir.serializer.FhirResourceDeserializer;
+import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsHooksExtension;
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceJson;
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceRequestContextJson;
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceRequestJson;
-import ca.uhn.hapi.fhir.cdshooks.svc.CdsServiceRegistryImpl;
-import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.DeserializationContext;
-import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
-import com.fasterxml.jackson.databind.module.SimpleModule;
+import jakarta.annotation.Nonnull;
import org.hl7.fhir.instance.model.api.IBaseResource;
-import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;
-public class CdsServiceRequestJsonDeserializer extends StdDeserializer {
-
- private final CdsServiceRegistryImpl myCdsServiceRegistry;
+public class CdsServiceRequestJsonDeserializer {
private final ObjectMapper myObjectMapper;
private final FhirContext myFhirContext;
private final IParser myParser;
- public CdsServiceRequestJsonDeserializer(CdsServiceRegistryImpl theCdsServiceRegistry, FhirContext theFhirContext) {
- super(CdsServiceRequestJson.class);
- myCdsServiceRegistry = theCdsServiceRegistry;
+ public CdsServiceRequestJsonDeserializer(
+ @Nonnull FhirContext theFhirContext, @Nonnull ObjectMapper theObjectMapper) {
myFhirContext = theFhirContext;
myParser = myFhirContext.newJsonParser().setPrettyPrint(true);
- // We create a new ObjectMapper instead of using the one from the ApplicationContext to avoid an infinite loop
- // during deserialization.
- myObjectMapper = new ObjectMapper();
- configureObjectMapper(myObjectMapper);
+ myObjectMapper = theObjectMapper;
}
- @Override
- public CdsServiceRequestJson deserialize(JsonParser theJsonParser, DeserializationContext theDeserializationContext)
- throws IOException {
- final JsonNode cdsServiceRequestJsonNode = theJsonParser.getCodec().readTree(theJsonParser);
- final JsonNode hookNode = cdsServiceRequestJsonNode.get("hook");
- final JsonNode extensionNode = cdsServiceRequestJsonNode.get("extension");
- final JsonNode requestContext = cdsServiceRequestJsonNode.get("context");
- final CdsServiceRequestJson cdsServiceRequestJson =
- myObjectMapper.treeToValue(cdsServiceRequestJsonNode, CdsServiceRequestJson.class);
- if (extensionNode != null) {
- CdsHooksExtension myRequestExtension = deserializeExtension(hookNode.textValue(), extensionNode.toString());
- cdsServiceRequestJson.setExtension(myRequestExtension);
+ public CdsServiceRequestJson deserialize(
+ @Nonnull CdsServiceJson theCdsServiceJson, @Nonnull Object theCdsServiceRequestJson) {
+ final JsonNode cdsServiceRequestJsonNode =
+ myObjectMapper.convertValue(theCdsServiceRequestJson, JsonNode.class);
+ final JsonNode contextNode = cdsServiceRequestJsonNode.get("context");
+ validateHookInstance(cdsServiceRequestJsonNode.get("hookInstance"));
+ validateHook(cdsServiceRequestJsonNode.get("hook"));
+ validateContext(contextNode);
+ try {
+ final JsonNode extensionNode = cdsServiceRequestJsonNode.get("extension");
+ final CdsServiceRequestJson cdsServiceRequestJson =
+ myObjectMapper.convertValue(cdsServiceRequestJsonNode, CdsServiceRequestJson.class);
+ LinkedHashMap map = myObjectMapper.readValue(contextNode.toString(), LinkedHashMap.class);
+ cdsServiceRequestJson.setContext(deserializeContext(map));
+ if (extensionNode != null) {
+ CdsHooksExtension myRequestExtension =
+ deserializeExtension(theCdsServiceJson, extensionNode.toString());
+ cdsServiceRequestJson.setExtension(myRequestExtension);
+ }
+ return cdsServiceRequestJson;
+ } catch (JsonProcessingException | IllegalArgumentException theEx) {
+ throw new InvalidRequestException(Msg.code(2551) + "Invalid CdsServiceRequest received. " + theEx);
}
- if (requestContext != null) {
- LinkedHashMap map =
- myObjectMapper.readValue(requestContext.toString(), LinkedHashMap.class);
- cdsServiceRequestJson.setContext(deserializeRequestContext(map));
- }
- return cdsServiceRequestJson;
}
- void configureObjectMapper(ObjectMapper theObjectMapper) {
- SimpleModule module = new SimpleModule();
- module.addDeserializer(IBaseResource.class, new FhirResourceDeserializer(myFhirContext));
- theObjectMapper.registerModule(module);
- // set this as we will need to ignore properties which are not defined by specific implementation.
- theObjectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
- }
-
- CdsHooksExtension deserializeExtension(String theServiceId, String theExtension) throws JsonProcessingException {
- final CdsServiceJson cdsServicesJson = myCdsServiceRegistry.getCdsServiceJson(theServiceId);
- Class extends CdsHooksExtension> extensionClass = cdsServicesJson.getExtensionClass();
- if (extensionClass == null) {
- return null;
- }
- return myObjectMapper.readValue(theExtension, extensionClass);
- }
-
- CdsServiceRequestContextJson deserializeRequestContext(LinkedHashMap theMap)
+ CdsServiceRequestContextJson deserializeContext(LinkedHashMap theMap)
throws JsonProcessingException {
final CdsServiceRequestContextJson cdsServiceRequestContextJson = new CdsServiceRequestContextJson();
for (Map.Entry entry : theMap.entrySet()) {
@@ -114,4 +90,31 @@ public class CdsServiceRequestJsonDeserializer extends StdDeserializer extensionClass = theCdsServiceJson.getExtensionClass();
+ if (extensionClass == null) {
+ return null;
+ }
+ return myObjectMapper.readValue(theExtension, extensionClass);
+ }
+
+ private void validateHook(JsonNode hookIdNode) {
+ if (hookIdNode == null) {
+ throw new InvalidRequestException(Msg.code(2549) + "hook cannot be null for a CdsServiceRequest.");
+ }
+ }
+
+ private void validateHookInstance(JsonNode hookInstanceNode) {
+ if (hookInstanceNode == null) {
+ throw new InvalidRequestException(Msg.code(2548) + "hookInstance cannot be null for a CdsServiceRequest.");
+ }
+ }
+
+ private void validateContext(JsonNode requestContextNode) {
+ if (requestContextNode == null) {
+ throw new InvalidRequestException(Msg.code(2550) + "context cannot be null for a CdsServiceRequest.");
+ }
+ }
}
diff --git a/hapi-fhir-server-cds-hooks/src/main/java/ca/uhn/hapi/fhir/cdshooks/svc/CdsServiceRegistryImpl.java b/hapi-fhir-server-cds-hooks/src/main/java/ca/uhn/hapi/fhir/cdshooks/svc/CdsServiceRegistryImpl.java
index 720fca731d7..8613dee9554 100644
--- a/hapi-fhir-server-cds-hooks/src/main/java/ca/uhn/hapi/fhir/cdshooks/svc/CdsServiceRegistryImpl.java
+++ b/hapi-fhir-server-cds-hooks/src/main/java/ca/uhn/hapi/fhir/cdshooks/svc/CdsServiceRegistryImpl.java
@@ -20,7 +20,6 @@
package ca.uhn.hapi.fhir.cdshooks.svc;
import ca.uhn.fhir.context.ConfigurationException;
-import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import ca.uhn.hapi.fhir.cdshooks.api.ICdsMethod;
@@ -38,7 +37,6 @@ import ca.uhn.hapi.fhir.cdshooks.svc.cr.discovery.ICrDiscoveryServiceFactory;
import ca.uhn.hapi.fhir.cdshooks.svc.prefetch.CdsPrefetchSvc;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.module.SimpleModule;
import com.google.common.annotations.VisibleForTesting;
import jakarta.annotation.Nonnull;
import jakarta.annotation.PostConstruct;
@@ -50,7 +48,7 @@ import java.util.function.Function;
public class CdsServiceRegistryImpl implements ICdsServiceRegistry {
private static final Logger ourLog = LoggerFactory.getLogger(CdsServiceRegistryImpl.class);
-
+ private final CdsServiceRequestJsonDeserializer myCdsServiceRequestJsonDeserializer;
private CdsServiceCache myServiceCache;
private final CdsHooksContextBooter myCdsHooksContextBooter;
@@ -65,19 +63,13 @@ public class CdsServiceRegistryImpl implements ICdsServiceRegistry {
ObjectMapper theObjectMapper,
ICdsCrServiceFactory theCdsCrServiceFactory,
ICrDiscoveryServiceFactory theCrDiscoveryServiceFactory,
- FhirContext theFhirContext) {
+ CdsServiceRequestJsonDeserializer theCdsServiceRequestJsonDeserializer) {
myCdsHooksContextBooter = theCdsHooksContextBooter;
myCdsPrefetchSvc = theCdsPrefetchSvc;
myObjectMapper = theObjectMapper;
- // registering this deserializer here instead of
- // CdsHooksObjectMapperFactory to avoid circular
- // dependency
- SimpleModule module = new SimpleModule();
- module.addDeserializer(
- CdsServiceRequestJson.class, new CdsServiceRequestJsonDeserializer(this, theFhirContext));
- myObjectMapper.registerModule(module);
myCdsCrServiceFactory = theCdsCrServiceFactory;
myCrDiscoveryServiceFactory = theCrDiscoveryServiceFactory;
+ myCdsServiceRequestJsonDeserializer = theCdsServiceRequestJsonDeserializer;
}
@PostConstruct
@@ -91,10 +83,13 @@ public class CdsServiceRegistryImpl implements ICdsServiceRegistry {
}
@Override
- public CdsServiceResponseJson callService(String theServiceId, CdsServiceRequestJson theCdsServiceRequestJson) {
+ public CdsServiceResponseJson callService(String theServiceId, Object theCdsServiceRequestJson) {
+ final CdsServiceJson cdsServiceJson = getCdsServiceJson(theServiceId);
+ final CdsServiceRequestJson deserializedRequest =
+ myCdsServiceRequestJsonDeserializer.deserialize(cdsServiceJson, theCdsServiceRequestJson);
ICdsServiceMethod serviceMethod = (ICdsServiceMethod) getCdsServiceMethodOrThrowException(theServiceId);
- myCdsPrefetchSvc.augmentRequest(theCdsServiceRequestJson, serviceMethod);
- Object response = serviceMethod.invoke(myObjectMapper, theCdsServiceRequestJson, theServiceId);
+ myCdsPrefetchSvc.augmentRequest(deserializedRequest, serviceMethod);
+ Object response = serviceMethod.invoke(myObjectMapper, deserializedRequest, theServiceId);
return encodeServiceResponse(theServiceId, response);
}
diff --git a/hapi-fhir-server-cds-hooks/src/test/java/ca/uhn/hapi/fhir/cdshooks/controller/CdsHooksControllerTest.java b/hapi-fhir-server-cds-hooks/src/test/java/ca/uhn/hapi/fhir/cdshooks/controller/CdsHooksControllerTest.java
index e6067fc16f4..22065764b41 100644
--- a/hapi-fhir-server-cds-hooks/src/test/java/ca/uhn/hapi/fhir/cdshooks/controller/CdsHooksControllerTest.java
+++ b/hapi-fhir-server-cds-hooks/src/test/java/ca/uhn/hapi/fhir/cdshooks/controller/CdsHooksControllerTest.java
@@ -5,6 +5,7 @@ import ca.uhn.hapi.fhir.cdshooks.api.ICdsServiceRegistry;
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceFeebackOutcomeEnum;
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceFeedbackJson;
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceJson;
+import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceRequestContextJson;
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceRequestJson;
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceResponseCardJson;
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceResponseJson;
@@ -118,6 +119,7 @@ public class CdsHooksControllerTest {
request.setHookInstance(TEST_HOOK_INSTANCE);
request.setHook(HelloWorldService.TEST_HOOK);
request.setFhirServer(TEST_FHIR_SERVER);
+ request.setContext( withCdsServiceRequestContext());
String requestBody = myObjectMapper.writeValueAsString(request);
@@ -142,8 +144,9 @@ public class CdsHooksControllerTest {
CdsServiceRequestJson request = new CdsServiceRequestJson();
request.setExtension(requestExtension);
request.setFhirServer(TEST_FHIR_SERVER);
- request.setHook(HelloWorldService.TEST_HOOK_UNIVERSE_ID);
-
+ request.setHook(HelloWorldService.TEST_HOOK);
+ request.setContext(withCdsServiceRequestContext());
+ request.setHookInstance(UUID.randomUUID().toString());
String requestBody = myObjectMapper.writeValueAsString(request);
@@ -163,6 +166,7 @@ public class CdsHooksControllerTest {
request.setHookInstance(TEST_HOOK_INSTANCE);
request.setHook(HelloWorldService.TEST_HOOK);
request.setFhirServer(TEST_FHIR_SERVER);
+ request.setContext(withCdsServiceRequestContext());
String requestBody = myObjectMapper.writeValueAsString(request);
@@ -268,4 +272,11 @@ public class CdsHooksControllerTest {
return JsonUtil.serialize(input, true);
}
+ @Nonnull
+ private static CdsServiceRequestContextJson withCdsServiceRequestContext() {
+ CdsServiceRequestContextJson cdsServiceRequestContextJson = new CdsServiceRequestContextJson();
+ cdsServiceRequestContextJson.put("patientId", "Patient/123");
+ return cdsServiceRequestContextJson;
+ }
+
}
diff --git a/hapi-fhir-server-cds-hooks/src/test/java/ca/uhn/hapi/fhir/cdshooks/serializer/CdsServiceRequestJsonDeserializerTest.java b/hapi-fhir-server-cds-hooks/src/test/java/ca/uhn/hapi/fhir/cdshooks/serializer/CdsServiceRequestJsonDeserializerTest.java
index 0e1e659cc8a..ecd8176ce6a 100644
--- a/hapi-fhir-server-cds-hooks/src/test/java/ca/uhn/hapi/fhir/cdshooks/serializer/CdsServiceRequestJsonDeserializerTest.java
+++ b/hapi-fhir-server-cds-hooks/src/test/java/ca/uhn/hapi/fhir/cdshooks/serializer/CdsServiceRequestJsonDeserializerTest.java
@@ -1,106 +1,152 @@
package ca.uhn.hapi.fhir.cdshooks.serializer;
import ca.uhn.fhir.context.FhirContext;
-import ca.uhn.hapi.fhir.cdshooks.api.json.CdsHooksExtension;
+import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceJson;
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceRequestContextJson;
+import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceRequestJson;
import ca.uhn.hapi.fhir.cdshooks.custom.extensions.model.ExampleExtension;
-import ca.uhn.hapi.fhir.cdshooks.svc.CdsServiceRegistryImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
+import jakarta.annotation.Nonnull;
import org.hl7.fhir.r4.model.Patient;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.Mock;
-import org.mockito.junit.jupiter.MockitoExtension;
import java.util.LinkedHashMap;
+import java.util.UUID;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.doReturn;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
-@ExtendWith(MockitoExtension.class)
class CdsServiceRequestJsonDeserializerTest {
- @Mock
- private CdsServiceRegistryImpl myCdsServiceRegistry;
+ private static final String SERVICE_ID = "service-id";
+ private static final String EXAMPLE_PROPERTY_VALUE = "example-value";
+ private static final String EXAMPLE_PROPERTY_KEY = "example-property";
+ private static final String HOOK_ID = "hook-id";
private final FhirContext myFhirContext = FhirContext.forR4();
+ private final ObjectMapper myObjectMapper = new ObjectMapper();
private CdsServiceRequestJsonDeserializer myFixture;
@BeforeEach()
void setup() {
- myFixture = new CdsServiceRequestJsonDeserializer(myCdsServiceRegistry, myFhirContext);
+ myFixture = new CdsServiceRequestJsonDeserializer(myFhirContext, myObjectMapper);
}
@Test
- void configureObjectMapper() {
+ void deserialize_shouldDeserialize_whenValidCdsServiceRequestWithExtensionReceived() {
// setup
- ObjectMapper input = new ObjectMapper();
+ final CdsServiceJson cdsServiceJson = withCdsServiceJsonIncludingExtensionClass();
+ final LinkedHashMap extension = withExtension();
+ final LinkedHashMap request = withRequest(extension);
+ request.put("context", withContext());
// execute
- myFixture.configureObjectMapper(input);
+ final CdsServiceRequestJson actual = myFixture.deserialize(cdsServiceJson, request);
// validate
- assertThat(input.getRegisteredModuleIds()).hasSize(1);
+ assertThat(actual.getExtension()).isInstanceOf(ExampleExtension.class);
+ final ExampleExtension actualExtension = (ExampleExtension) actual.getExtension();
+ assertThat(actualExtension.getExampleProperty()).isEqualTo(EXAMPLE_PROPERTY_VALUE);
}
@Test
- void deserializeExtensionWhenClassFoundShouldDeserializeExtension() throws JsonProcessingException {
+ void deserialize_shouldIgnoreExtraFieldsInsideExtension_whenExtensionContainsMoreFieldsThanDefinedInClass() {
+ // setup
+ final CdsServiceJson cdsServiceJson = withCdsServiceJsonIncludingExtensionClass();
+ final LinkedHashMap extension = withExtension();
+ extension.put("example-extra-property", "example-extra-value");
+ final LinkedHashMap request = withRequest(extension);
+ request.put("context", withContext());
+ // execute
+ final CdsServiceRequestJson actual = myFixture.deserialize(cdsServiceJson, request);
+ // validate
+ assertThat(actual.getExtension()).isInstanceOf(ExampleExtension.class);
+ final ExampleExtension actualExtension = (ExampleExtension) actual.getExtension();
+ assertThat(actualExtension.getExampleProperty()).isEqualTo(EXAMPLE_PROPERTY_VALUE);
+ assertThat(actual.getContext().get("encounterId")).isEqualTo("Encounter/123");
+ }
+
+ @Nonnull
+ private static LinkedHashMap withContext() {
+ final LinkedHashMap context = new LinkedHashMap<>();
+ context.put("encounterId", "Encounter/123");
+ return context;
+ }
+
+ @Test
+ void deserialize_shouldThrow_whenCdsServiceRequestIncludesInvalidProperty() {
+ // setup
+ final CdsServiceJson cdsServiceJson = withCdsServiceJsonIncludingExtensionClass();
+ final LinkedHashMap extension = withExtension();
+ final LinkedHashMap request = withRequest(extension);
+ request.put("invalid-key", "some-value");
+ request.put("context", withContext());
+ // execute & validate
+ assertThatThrownBy(
+ () -> myFixture.deserialize(cdsServiceJson, request))
+ .isInstanceOf(InvalidRequestException.class)
+ .hasMessageContaining("HAPI-2551:")
+ .hasMessageContaining("Invalid CdsServiceRequest received.");
+ }
+
+ @Test
+ void deserialize_shouldReturnNullExtension_whenNotClassFound() {
// setup
- final String serviceId = "service-id";
- final String extension = """
- {
- "example-property": "example-value"
- }
- """;
final CdsServiceJson cdsServiceJson = new CdsServiceJson();
- cdsServiceJson.setId(serviceId);
- cdsServiceJson.setExtensionClass(ExampleExtension.class);
- doReturn(cdsServiceJson).when(myCdsServiceRegistry).getCdsServiceJson(serviceId);
+ cdsServiceJson.setId(SERVICE_ID);
+ final LinkedHashMap extension = withExtension();
+ extension.put("example-extra-property", "example-extra-value");
+ final LinkedHashMap request = withRequest(extension);
+ request.put("context", withContext());
// execute
- final ExampleExtension actual = (ExampleExtension) myFixture.deserializeExtension(serviceId, extension);
+ final CdsServiceRequestJson actual = myFixture.deserialize(cdsServiceJson, request);
// validate
- assertThat(actual.getExampleProperty()).isEqualTo("example-value");
+ assertThat(actual.getExtension()).isNull();
}
@Test
- void deserializeExtensionWhenClassFoundButExtensionHasExtraPropertiesShouldIgnoreExtraProperties() throws JsonProcessingException {
+ void deserialize_shouldThrow_whenHookNotFoundInRequest() {
// setup
- final String serviceId = "service-id";
- final String extension = """
- {
- "example-property": "example-value",
- "example-extra-property": "example-extra-value"
- }
- """;
- final CdsServiceJson cdsServiceJson = new CdsServiceJson();
- cdsServiceJson.setId(serviceId);
- cdsServiceJson.setExtensionClass(ExampleExtension.class);
- doReturn(cdsServiceJson).when(myCdsServiceRegistry).getCdsServiceJson(serviceId);
- // execute
- final ExampleExtension actual = (ExampleExtension) myFixture.deserializeExtension(serviceId, extension);
- // validate
- assertThat(actual.getExampleProperty()).isEqualTo("example-value");
+ final CdsServiceJson cdsServiceJson = withCdsServiceJsonIncludingExtensionClass();
+ final LinkedHashMap request = new LinkedHashMap<>();
+ request.put("context", withContext());
+ request.put("hookInstance", UUID.randomUUID().toString());
+ // execute and validate
+ assertThatThrownBy(() -> myFixture.deserialize(cdsServiceJson, request))
+ .isInstanceOf(InvalidRequestException.class)
+ .hasMessageContaining("HAPI-2549:")
+ .hasMessageContaining("hook cannot be null for a CdsServiceRequest.");
}
@Test
- void deserializeExtensionWhenNotClassFoundShouldReturnNull() throws JsonProcessingException {
+ void deserialize_shouldThrow_whenContextNotFoundInRequest() {
// setup
- final String serviceId = "service-id";
- final String extension = """
- {
- "example-property": "example-value"
- }
- """;
- final CdsServiceJson cdsServiceJson = new CdsServiceJson();
- cdsServiceJson.setId(serviceId);
- doReturn(cdsServiceJson).when(myCdsServiceRegistry).getCdsServiceJson(serviceId);
- // execute
- final CdsHooksExtension actual = myFixture.deserializeExtension(serviceId, extension);
- // validate
- assertThat(actual).isNull();
+ final CdsServiceJson cdsServiceJson = withCdsServiceJsonIncludingExtensionClass();
+ final LinkedHashMap request = new LinkedHashMap<>();
+ request.put("hook", HOOK_ID);
+ request.put("hookInstance", UUID.randomUUID().toString());
+ // execute and validate
+ assertThatThrownBy(() -> myFixture.deserialize(cdsServiceJson, request))
+ .isInstanceOf(InvalidRequestException.class)
+ .hasMessageContaining("HAPI-2550:")
+ .hasMessageContaining("context cannot be null for a CdsServiceRequest.");
}
@Test
- void deserializeRequestContextShouldDeserializeValidContext() throws JsonProcessingException {
+ void deserialize_shouldThrow_whenHookInstanceNotFoundInRequest() {
+ // setup
+ final CdsServiceJson cdsServiceJson = withCdsServiceJsonIncludingExtensionClass();
+ final LinkedHashMap request = new LinkedHashMap<>();
+ request.put("context", withContext());
+ request.put("hook", HOOK_ID);
+ // execute and validate
+ assertThatThrownBy(() -> myFixture.deserialize(cdsServiceJson, request))
+ .isInstanceOf(InvalidRequestException.class)
+ .hasMessageContaining("HAPI-2548:")
+ .hasMessageContaining("hookInstance cannot be null for a CdsServiceRequest.");
+ }
+
+ @Test
+ void deserializeRequestContext_shouldDeserialize_whenContextIsValid() throws JsonProcessingException {
// setup
final String encounterId = "123";
final Patient patientContext = new Patient();
@@ -109,9 +155,34 @@ class CdsServiceRequestJsonDeserializerTest {
input.put("encounterId", encounterId);
input.put("patient", patientContext);
// execute
- final CdsServiceRequestContextJson actual = myFixture.deserializeRequestContext(input);
+ final CdsServiceRequestContextJson actual = myFixture.deserializeContext(input);
// validate
assertThat(actual.get("encounterId")).isEqualTo(encounterId);
assertThat(actual.get("patient")).usingRecursiveComparison().isEqualTo(patientContext);
}
+
+ @Nonnull
+ private static LinkedHashMap withExtension() {
+ final LinkedHashMap extension = new LinkedHashMap<>();
+ extension.put(EXAMPLE_PROPERTY_KEY, EXAMPLE_PROPERTY_VALUE);
+ return extension;
+ }
+
+ @Nonnull
+ private static CdsServiceJson withCdsServiceJsonIncludingExtensionClass() {
+ final CdsServiceJson cdsServiceJson = new CdsServiceJson();
+ cdsServiceJson.setId(SERVICE_ID);
+ cdsServiceJson.setExtensionClass(ExampleExtension.class);
+ cdsServiceJson.setHook(HOOK_ID);
+ return cdsServiceJson;
+ }
+
+ @Nonnull
+ private static LinkedHashMap withRequest(@Nonnull LinkedHashMap theExtension) {
+ final LinkedHashMap request = new LinkedHashMap<>();
+ request.put("extension", theExtension);
+ request.put("hookInstance", UUID.randomUUID().toString());
+ request.put("hook", HOOK_ID);
+ return request;
+ }
}
diff --git a/hapi-fhir-server-cds-hooks/src/test/java/ca/uhn/hapi/fhir/cdshooks/svc/CdsServiceRegistryImplTest.java b/hapi-fhir-server-cds-hooks/src/test/java/ca/uhn/hapi/fhir/cdshooks/svc/CdsServiceRegistryImplTest.java
index 4bb7f699331..3ba49b9f5f6 100644
--- a/hapi-fhir-server-cds-hooks/src/test/java/ca/uhn/hapi/fhir/cdshooks/svc/CdsServiceRegistryImplTest.java
+++ b/hapi-fhir-server-cds-hooks/src/test/java/ca/uhn/hapi/fhir/cdshooks/svc/CdsServiceRegistryImplTest.java
@@ -1,10 +1,10 @@
package ca.uhn.hapi.fhir.cdshooks.svc;
import ca.uhn.fhir.context.ConfigurationException;
-import ca.uhn.fhir.context.FhirContext;
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceFeedbackJson;
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceJson;
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceResponseJson;
+import ca.uhn.hapi.fhir.cdshooks.serializer.CdsServiceRequestJsonDeserializer;
import ca.uhn.hapi.fhir.cdshooks.svc.cr.ICdsCrServiceFactory;
import ca.uhn.hapi.fhir.cdshooks.svc.cr.discovery.ICrDiscoveryServiceFactory;
import ca.uhn.hapi.fhir.cdshooks.svc.prefetch.CdsPrefetchSvc;
@@ -33,13 +33,14 @@ class CdsServiceRegistryImplTest {
private ICrDiscoveryServiceFactory myCrDiscoveryServiceFactory;
@Mock
private CdsServiceCache myCdsServiceCache;
+ @Mock
+ private CdsServiceRequestJsonDeserializer myCdsServiceRequestJsonDeserializer;
private final ObjectMapper myObjectMapper = new ObjectMapper();
- private final FhirContext myFhirContext = FhirContext.forR4();
private CdsServiceRegistryImpl myFixture;
@BeforeEach()
void setup() {
- myFixture = new CdsServiceRegistryImpl(myCdsHooksContextBooter, myCdsPrefetchSvc, myObjectMapper, myCdsCrServiceFactory, myCrDiscoveryServiceFactory, myFhirContext);
+ myFixture = new CdsServiceRegistryImpl(myCdsHooksContextBooter, myCdsPrefetchSvc, myObjectMapper, myCdsCrServiceFactory, myCrDiscoveryServiceFactory, myCdsServiceRequestJsonDeserializer);
}
@Test
diff --git a/hapi-fhir-server-mdm/pom.xml b/hapi-fhir-server-mdm/pom.xml
index 5e2b9ee3e05..95abe58fe85 100644
--- a/hapi-fhir-server-mdm/pom.xml
+++ b/hapi-fhir-server-mdm/pom.xml
@@ -7,7 +7,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-server-openapi/pom.xml b/hapi-fhir-server-openapi/pom.xml
index 8850b3445eb..89e2600dd02 100644
--- a/hapi-fhir-server-openapi/pom.xml
+++ b/hapi-fhir-server-openapi/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-server/pom.xml b/hapi-fhir-server/pom.xml
index 457cd28044c..be0015008a1 100644
--- a/hapi-fhir-server/pom.xml
+++ b/hapi-fhir-server/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-serviceloaders/hapi-fhir-caching-api/pom.xml b/hapi-fhir-serviceloaders/hapi-fhir-caching-api/pom.xml
index cee8e510785..39836ddc8e4 100644
--- a/hapi-fhir-serviceloaders/hapi-fhir-caching-api/pom.xml
+++ b/hapi-fhir-serviceloaders/hapi-fhir-caching-api/pom.xml
@@ -7,7 +7,7 @@
hapi-fhir-serviceloaders
ca.uhn.hapi.fhir
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../pom.xml
diff --git a/hapi-fhir-serviceloaders/hapi-fhir-caching-caffeine/pom.xml b/hapi-fhir-serviceloaders/hapi-fhir-caching-caffeine/pom.xml
index 428f89dc3d4..e8eae8ff086 100644
--- a/hapi-fhir-serviceloaders/hapi-fhir-caching-caffeine/pom.xml
+++ b/hapi-fhir-serviceloaders/hapi-fhir-caching-caffeine/pom.xml
@@ -7,7 +7,7 @@
hapi-fhir-serviceloaders
ca.uhn.hapi.fhir
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../pom.xml
@@ -21,7 +21,7 @@
ca.uhn.hapi.fhir
hapi-fhir-caching-api
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
diff --git a/hapi-fhir-serviceloaders/hapi-fhir-caching-guava/pom.xml b/hapi-fhir-serviceloaders/hapi-fhir-caching-guava/pom.xml
index 8dc3778e4ab..89e57090090 100644
--- a/hapi-fhir-serviceloaders/hapi-fhir-caching-guava/pom.xml
+++ b/hapi-fhir-serviceloaders/hapi-fhir-caching-guava/pom.xml
@@ -7,7 +7,7 @@
hapi-fhir-serviceloaders
ca.uhn.hapi.fhir
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../pom.xml
diff --git a/hapi-fhir-serviceloaders/hapi-fhir-caching-testing/pom.xml b/hapi-fhir-serviceloaders/hapi-fhir-caching-testing/pom.xml
index f3a6f30fdc7..1d43c70ed0e 100644
--- a/hapi-fhir-serviceloaders/hapi-fhir-caching-testing/pom.xml
+++ b/hapi-fhir-serviceloaders/hapi-fhir-caching-testing/pom.xml
@@ -7,7 +7,7 @@
hapi-fhir
ca.uhn.hapi.fhir
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../../pom.xml
diff --git a/hapi-fhir-serviceloaders/pom.xml b/hapi-fhir-serviceloaders/pom.xml
index dc407e19ef3..13859f26fee 100644
--- a/hapi-fhir-serviceloaders/pom.xml
+++ b/hapi-fhir-serviceloaders/pom.xml
@@ -5,7 +5,7 @@
hapi-deployable-pom
ca.uhn.hapi.fhir
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-autoconfigure/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-autoconfigure/pom.xml
index 58fdac09a26..7301924dde5 100644
--- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-autoconfigure/pom.xml
+++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-autoconfigure/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-apache/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-apache/pom.xml
index 7a634812925..137bd075790 100644
--- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-apache/pom.xml
+++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-apache/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir-spring-boot-samples
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
hapi-fhir-spring-boot-sample-client-apache
diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-okhttp/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-okhttp/pom.xml
index 7fd06fcf3bf..106a0cf80bf 100644
--- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-okhttp/pom.xml
+++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-okhttp/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir-spring-boot-samples
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jersey/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jersey/pom.xml
index 1f735d48418..0c2e4ed2f08 100644
--- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jersey/pom.xml
+++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jersey/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir-spring-boot-samples
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/pom.xml
index 62f9c031867..6c62b628f06 100644
--- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/pom.xml
+++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir-spring-boot
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-starter/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-starter/pom.xml
index b65824baf92..52a41c7dc64 100644
--- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-starter/pom.xml
+++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-starter/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-spring-boot/pom.xml b/hapi-fhir-spring-boot/pom.xml
index d7c752647e1..4877a32ed4f 100644
--- a/hapi-fhir-spring-boot/pom.xml
+++ b/hapi-fhir-spring-boot/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../pom.xml
diff --git a/hapi-fhir-sql-migrate/pom.xml b/hapi-fhir-sql-migrate/pom.xml
index 429c1914686..08f9decc2d8 100644
--- a/hapi-fhir-sql-migrate/pom.xml
+++ b/hapi-fhir-sql-migrate/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/ForceIdMigrationFixTask.java b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/ForceIdMigrationFixTask.java
index 07607a90845..543fd942892 100644
--- a/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/ForceIdMigrationFixTask.java
+++ b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/ForceIdMigrationFixTask.java
@@ -89,7 +89,7 @@ public class ForceIdMigrationFixTask extends BaseTask {
" set fhir_id = coalesce( "
+
// case 5.
- " trim(fhir_id), "
+ trimFhirId()
+
// case 3
" (select f.forced_id from hfj_forced_id f where f.resource_pid = res_id), "
@@ -109,6 +109,22 @@ public class ForceIdMigrationFixTask extends BaseTask {
}
}
+ private String trimFhirId() {
+ switch (getDriverType()) {
+ case MSSQL_2012:
+ return " LTRIM(RTRIM(fhir_id)), ";
+ case H2_EMBEDDED:
+ case DERBY_EMBEDDED:
+ case MARIADB_10_1:
+ case MYSQL_5_7:
+ case POSTGRES_9_4:
+ case ORACLE_12C:
+ case COCKROACHDB_21_1:
+ default:
+ return " trim(fhir_id), ";
+ }
+ }
+
private String getWhereClauseByDBType() {
switch (getDriverType()) {
case MSSQL_2012:
diff --git a/hapi-fhir-storage-batch2-jobs/pom.xml b/hapi-fhir-storage-batch2-jobs/pom.xml
index 6ad5389cf0f..bcab73f8584 100644
--- a/hapi-fhir-storage-batch2-jobs/pom.xml
+++ b/hapi-fhir-storage-batch2-jobs/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-storage-batch2-test-utilities/pom.xml b/hapi-fhir-storage-batch2-test-utilities/pom.xml
index c5433cf41b0..e695c5bed3f 100644
--- a/hapi-fhir-storage-batch2-test-utilities/pom.xml
+++ b/hapi-fhir-storage-batch2-test-utilities/pom.xml
@@ -7,7 +7,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-storage-batch2/pom.xml b/hapi-fhir-storage-batch2/pom.xml
index 28434f97f04..682fa7b8e69 100644
--- a/hapi-fhir-storage-batch2/pom.xml
+++ b/hapi-fhir-storage-batch2/pom.xml
@@ -7,7 +7,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-storage-cr/pom.xml b/hapi-fhir-storage-cr/pom.xml
index 3cc3d4e2d6c..775a22c5e41 100644
--- a/hapi-fhir-storage-cr/pom.xml
+++ b/hapi-fhir-storage-cr/pom.xml
@@ -7,7 +7,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
@@ -145,6 +145,20 @@
jakarta.xml.bind-api
+
+
+ ca.uhn.hapi.fhir
+ hapi-fhir-jpaserver-base
+ ${project.version}
+
+
+
+ org.glassfish
+ jakarta.json
+
+
+
+
org.testcontainers
diff --git a/hapi-fhir-storage-cr/src/main/java/ca/uhn/fhir/cr/common/IRepositoryFactory.java b/hapi-fhir-storage-cr/src/main/java/ca/uhn/fhir/cr/common/IRepositoryFactory.java
index 24963a9cc85..82094e62a6c 100644
--- a/hapi-fhir-storage-cr/src/main/java/ca/uhn/fhir/cr/common/IRepositoryFactory.java
+++ b/hapi-fhir-storage-cr/src/main/java/ca/uhn/fhir/cr/common/IRepositoryFactory.java
@@ -21,8 +21,10 @@ package ca.uhn.fhir.cr.common;
import ca.uhn.fhir.cr.repo.HapiFhirRepository;
import ca.uhn.fhir.rest.api.server.RequestDetails;
+import com.google.common.annotations.Beta;
@FunctionalInterface
+@Beta
public interface IRepositoryFactory {
HapiFhirRepository create(RequestDetails theRequestDetails);
}
diff --git a/hapi-fhir-storage-cr/src/main/java/ca/uhn/fhir/cr/common/RepositoryFactoryForRepositoryInterface.java b/hapi-fhir-storage-cr/src/main/java/ca/uhn/fhir/cr/common/RepositoryFactoryForRepositoryInterface.java
new file mode 100644
index 00000000000..a01f5736000
--- /dev/null
+++ b/hapi-fhir-storage-cr/src/main/java/ca/uhn/fhir/cr/common/RepositoryFactoryForRepositoryInterface.java
@@ -0,0 +1,31 @@
+/*-
+ * #%L
+ * HAPI FHIR - Clinical Reasoning
+ * %%
+ * Copyright (C) 2014 - 2024 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%
+ */
+package ca.uhn.fhir.cr.common;
+
+import ca.uhn.fhir.rest.api.server.RequestDetails;
+import org.opencds.cqf.fhir.api.Repository;
+
+/**
+ * Factory interface to return a {@link Repository} from a {@link RequestDetails}
+ */
+@FunctionalInterface
+public interface RepositoryFactoryForRepositoryInterface {
+ Repository create(RequestDetails theRequestDetails);
+}
diff --git a/hapi-fhir-storage-cr/src/main/java/ca/uhn/fhir/cr/config/RepositoryConfig.java b/hapi-fhir-storage-cr/src/main/java/ca/uhn/fhir/cr/config/RepositoryConfig.java
index fb40025f58a..93d4c0f58ce 100644
--- a/hapi-fhir-storage-cr/src/main/java/ca/uhn/fhir/cr/config/RepositoryConfig.java
+++ b/hapi-fhir-storage-cr/src/main/java/ca/uhn/fhir/cr/config/RepositoryConfig.java
@@ -20,6 +20,7 @@
package ca.uhn.fhir.cr.config;
import ca.uhn.fhir.cr.common.IRepositoryFactory;
+import ca.uhn.fhir.cr.common.RepositoryFactoryForRepositoryInterface;
import ca.uhn.fhir.cr.repo.HapiFhirRepository;
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
import ca.uhn.fhir.rest.server.RestfulServer;
@@ -28,8 +29,15 @@ import org.springframework.context.annotation.Configuration;
@Configuration
public class RepositoryConfig {
+
@Bean
IRepositoryFactory repositoryFactory(DaoRegistry theDaoRegistry, RestfulServer theRestfulServer) {
return rd -> new HapiFhirRepository(theDaoRegistry, rd, theRestfulServer);
}
+
+ @Bean
+ RepositoryFactoryForRepositoryInterface repositoryFactoryForInterface(
+ DaoRegistry theDaoRegistry, RestfulServer theRestfulServer) {
+ return rd -> new HapiFhirRepository(theDaoRegistry, rd, theRestfulServer);
+ }
}
diff --git a/hapi-fhir-storage-cr/src/main/java/ca/uhn/fhir/cr/config/r4/CrR4Config.java b/hapi-fhir-storage-cr/src/main/java/ca/uhn/fhir/cr/config/r4/CrR4Config.java
index 19466eba19b..3cdc398e0c0 100644
--- a/hapi-fhir-storage-cr/src/main/java/ca/uhn/fhir/cr/config/r4/CrR4Config.java
+++ b/hapi-fhir-storage-cr/src/main/java/ca/uhn/fhir/cr/config/r4/CrR4Config.java
@@ -22,6 +22,7 @@ package ca.uhn.fhir.cr.config.r4;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.cr.common.IRepositoryFactory;
+import ca.uhn.fhir.cr.common.RepositoryFactoryForRepositoryInterface;
import ca.uhn.fhir.cr.config.ProviderLoader;
import ca.uhn.fhir.cr.config.ProviderSelector;
import ca.uhn.fhir.cr.config.RepositoryConfig;
@@ -66,7 +67,8 @@ public class CrR4Config {
@Bean
IMeasureServiceFactory r4MeasureServiceFactory(
- IRepositoryFactory theRepositoryFactory, MeasureEvaluationOptions theEvaluationOptions) {
+ RepositoryFactoryForRepositoryInterface theRepositoryFactory,
+ MeasureEvaluationOptions theEvaluationOptions) {
return rd -> new R4MeasureService(theRepositoryFactory.create(rd), theEvaluationOptions);
}
diff --git a/hapi-fhir-storage-cr/src/test/java/ca/uhn/fhir/cr/TestCqlProperties.java b/hapi-fhir-storage-cr/src/main/java/ca/uhn/fhir/cr/config/test/TestCqlProperties.java
similarity index 92%
rename from hapi-fhir-storage-cr/src/test/java/ca/uhn/fhir/cr/TestCqlProperties.java
rename to hapi-fhir-storage-cr/src/main/java/ca/uhn/fhir/cr/config/test/TestCqlProperties.java
index b9c5c081728..1be7c4f3505 100644
--- a/hapi-fhir-storage-cr/src/test/java/ca/uhn/fhir/cr/TestCqlProperties.java
+++ b/hapi-fhir-storage-cr/src/main/java/ca/uhn/fhir/cr/config/test/TestCqlProperties.java
@@ -1,4 +1,23 @@
-package ca.uhn.fhir.cr;
+/*-
+ * #%L
+ * HAPI FHIR - Clinical Reasoning
+ * %%
+ * Copyright (C) 2014 - 2024 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%
+ */
+package ca.uhn.fhir.cr.config.test;
import org.cqframework.cql.cql2elm.CqlCompilerException;
import org.cqframework.cql.cql2elm.CqlCompilerOptions;
@@ -7,7 +26,9 @@ import org.cqframework.cql.cql2elm.LibraryBuilder;
import org.opencds.cqf.fhir.cql.CqlEngineOptions;
import org.opencds.cqf.fhir.cql.CqlOptions;
-
+/**
+ * Common CQL properties shared with downstream modules.
+ */
public class TestCqlProperties {
//cql settings
diff --git a/hapi-fhir-storage-cr/src/test/java/ca/uhn/fhir/cr/TestCrConfig.java b/hapi-fhir-storage-cr/src/main/java/ca/uhn/fhir/cr/config/test/TestCrConfig.java
similarity index 89%
rename from hapi-fhir-storage-cr/src/test/java/ca/uhn/fhir/cr/TestCrConfig.java
rename to hapi-fhir-storage-cr/src/main/java/ca/uhn/fhir/cr/config/test/TestCrConfig.java
index 4f42ae49d52..9a9f43a902f 100644
--- a/hapi-fhir-storage-cr/src/test/java/ca/uhn/fhir/cr/TestCrConfig.java
+++ b/hapi-fhir-storage-cr/src/main/java/ca/uhn/fhir/cr/config/test/TestCrConfig.java
@@ -1,4 +1,23 @@
-package ca.uhn.fhir.cr;
+/*-
+ * #%L
+ * HAPI FHIR - Clinical Reasoning
+ * %%
+ * Copyright (C) 2014 - 2024 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%
+ */
+package ca.uhn.fhir.cr.config.test;
import ca.uhn.fhir.batch2.jobs.reindex.ReindexProvider;
import ca.uhn.fhir.context.FhirContext;
@@ -47,6 +66,9 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
+/**
+ * Common hapi-fhir clinical reasoning config shared with downstream modules.
+ */
@Configuration
@Import({SubscriptionSubmitterConfig.class, SubscriptionChannelConfig.class})
public class TestCrConfig {
@@ -77,7 +99,9 @@ public class TestCrConfig {
}
@Bean
public TestCqlProperties testCqlProperties(){
- return new TestCqlProperties();}
+ return new TestCqlProperties();
+ }
+
@Bean
public JpaStorageSettings storageSettings() {
JpaStorageSettings storageSettings = new JpaStorageSettings();
@@ -87,12 +111,6 @@ public class TestCrConfig {
storageSettings.setResourceClientIdStrategy(JpaStorageSettings.ClientIdStrategyEnum.ANY);
return storageSettings;
}
-
- @Bean
- public PartitionHelper partitionHelper() {
- return new PartitionHelper();
- }
-
@Bean
public ModelManager modelManager(Map theGlobalModelCache) {
return new ModelManager(theGlobalModelCache);
diff --git a/hapi-fhir-storage-cr/src/test/java/ca/uhn/fhir/cr/r4/TestCrR4Config.java b/hapi-fhir-storage-cr/src/main/java/ca/uhn/fhir/cr/config/test/r4/TestCrR4Config.java
similarity index 88%
rename from hapi-fhir-storage-cr/src/test/java/ca/uhn/fhir/cr/r4/TestCrR4Config.java
rename to hapi-fhir-storage-cr/src/main/java/ca/uhn/fhir/cr/config/test/r4/TestCrR4Config.java
index e80eab49bc4..9e5b4c50466 100644
--- a/hapi-fhir-storage-cr/src/test/java/ca/uhn/fhir/cr/r4/TestCrR4Config.java
+++ b/hapi-fhir-storage-cr/src/main/java/ca/uhn/fhir/cr/config/test/r4/TestCrR4Config.java
@@ -1,9 +1,28 @@
-package ca.uhn.fhir.cr.r4;
+/*-
+ * #%L
+ * HAPI FHIR - Clinical Reasoning
+ * %%
+ * Copyright (C) 2014 - 2024 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%
+ */
+package ca.uhn.fhir.cr.config.test.r4;
-import ca.uhn.fhir.cr.TestCqlProperties;
-import ca.uhn.fhir.cr.TestCrConfig;
import ca.uhn.fhir.cr.common.CqlThreadFactory;
import ca.uhn.fhir.cr.config.r4.CrR4Config;
+import ca.uhn.fhir.cr.config.test.TestCqlProperties;
+import ca.uhn.fhir.cr.config.test.TestCrConfig;
import org.cqframework.cql.cql2elm.CqlCompilerOptions;
import org.cqframework.cql.cql2elm.model.CompiledLibrary;
import org.cqframework.cql.cql2elm.model.Model;
@@ -30,6 +49,9 @@ import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+/**
+ * Common hapi-fhir clinical reasoning config specifically for R4 shared with downstream modules.
+ */
@Configuration
@Import({TestCrConfig.class, CrR4Config.class})
public class TestCrR4Config {
diff --git a/hapi-fhir-storage-cr/src/test/java/ca/uhn/fhir/cr/TestHapiFhirCrPartitionConfig.java b/hapi-fhir-storage-cr/src/test/java/ca/uhn/fhir/cr/TestHapiFhirCrPartitionConfig.java
new file mode 100644
index 00000000000..6b95b55deed
--- /dev/null
+++ b/hapi-fhir-storage-cr/src/test/java/ca/uhn/fhir/cr/TestHapiFhirCrPartitionConfig.java
@@ -0,0 +1,10 @@
+package ca.uhn.fhir.cr;
+
+import org.springframework.context.annotation.Bean;
+
+public class TestHapiFhirCrPartitionConfig {
+ @Bean
+ public PartitionHelper partitionHelper() {
+ return new PartitionHelper();
+ }
+}
diff --git a/hapi-fhir-storage-cr/src/test/java/ca/uhn/fhir/cr/dstu3/TestCrDstu3Config.java b/hapi-fhir-storage-cr/src/test/java/ca/uhn/fhir/cr/dstu3/TestCrDstu3Config.java
index 39fc0b34651..a79d4968627 100644
--- a/hapi-fhir-storage-cr/src/test/java/ca/uhn/fhir/cr/dstu3/TestCrDstu3Config.java
+++ b/hapi-fhir-storage-cr/src/test/java/ca/uhn/fhir/cr/dstu3/TestCrDstu3Config.java
@@ -1,8 +1,9 @@
package ca.uhn.fhir.cr.dstu3;
-import ca.uhn.fhir.cr.TestCqlProperties;
-import ca.uhn.fhir.cr.TestCrConfig;
+import ca.uhn.fhir.cr.TestHapiFhirCrPartitionConfig;
+import ca.uhn.fhir.cr.config.test.TestCqlProperties;
import ca.uhn.fhir.cr.config.dstu3.CrDstu3Config;
+import ca.uhn.fhir.cr.config.test.TestCrConfig;
import org.cqframework.cql.cql2elm.CqlCompilerOptions;
import org.cqframework.cql.cql2elm.model.CompiledLibrary;
import org.cqframework.cql.cql2elm.model.Model;
@@ -26,6 +27,7 @@ import java.util.Set;
@Configuration
@Import({
+ TestHapiFhirCrPartitionConfig.class,
TestCrConfig.class,
CrDstu3Config.class
})
diff --git a/hapi-fhir-storage-cr/src/test/java/ca/uhn/fhir/cr/r4/BaseCrR4TestServer.java b/hapi-fhir-storage-cr/src/test/java/ca/uhn/fhir/cr/r4/BaseCrR4TestServer.java
index 686681d6352..49e31bad8c6 100644
--- a/hapi-fhir-storage-cr/src/test/java/ca/uhn/fhir/cr/r4/BaseCrR4TestServer.java
+++ b/hapi-fhir-storage-cr/src/test/java/ca/uhn/fhir/cr/r4/BaseCrR4TestServer.java
@@ -2,10 +2,12 @@ package ca.uhn.fhir.cr.r4;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.cr.IResourceLoader;
+import ca.uhn.fhir.cr.TestHapiFhirCrPartitionConfig;
import ca.uhn.fhir.cr.config.r4.ApplyOperationConfig;
import ca.uhn.fhir.cr.config.r4.ExtractOperationConfig;
import ca.uhn.fhir.cr.config.r4.PackageOperationConfig;
import ca.uhn.fhir.cr.config.r4.PopulateOperationConfig;
+import ca.uhn.fhir.cr.config.test.r4.TestCrR4Config;
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider;
@@ -38,6 +40,7 @@ import java.util.concurrent.TimeUnit;
@ContextConfiguration(classes = {
+ TestHapiFhirCrPartitionConfig.class,
TestCrR4Config.class,
ApplyOperationConfig.class,
ExtractOperationConfig.class,
diff --git a/hapi-fhir-storage-cr/src/test/java/ca/uhn/fhir/cr/r4/CrResourceListenerTests.java b/hapi-fhir-storage-cr/src/test/java/ca/uhn/fhir/cr/r4/CrResourceListenerTest.java
similarity index 95%
rename from hapi-fhir-storage-cr/src/test/java/ca/uhn/fhir/cr/r4/CrResourceListenerTests.java
rename to hapi-fhir-storage-cr/src/test/java/ca/uhn/fhir/cr/r4/CrResourceListenerTest.java
index 481999ed95a..f0205f86b5f 100644
--- a/hapi-fhir-storage-cr/src/test/java/ca/uhn/fhir/cr/r4/CrResourceListenerTests.java
+++ b/hapi-fhir-storage-cr/src/test/java/ca/uhn/fhir/cr/r4/CrResourceListenerTest.java
@@ -1,6 +1,6 @@
package ca.uhn.fhir.cr.r4;
-import ca.uhn.fhir.jpa.cache.ResourceChangeListenerCacheRefresherImpl;
+import ca.uhn.fhir.jpa.cache.IResourceChangeListenerCacheRefresher;
import ca.uhn.fhir.jpa.cache.ResourceChangeListenerRegistryImpl;
import org.hl7.fhir.r4.model.DateType;
import org.hl7.fhir.r4.model.IdType;
@@ -16,13 +16,13 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@ExtendWith(SpringExtension.class)
-public class CrResourceListenerTests extends BaseCrR4TestServer {
+public class CrResourceListenerTest extends BaseCrR4TestServer {
@Autowired
EvaluationSettings myEvaluationSettings;
@Autowired
ResourceChangeListenerRegistryImpl myResourceChangeListenerRegistry;
@Autowired
- ResourceChangeListenerCacheRefresherImpl myResourceChangeListenerCacheRefresher;
+ IResourceChangeListenerCacheRefresher myResourceChangeListenerCacheRefresher;
public MeasureReport runEvaluateMeasure(String periodStart, String periodEnd, String subject, String measureId, String reportType, String practitioner){
@@ -118,7 +118,7 @@ public class CrResourceListenerTests extends BaseCrR4TestServer {
myResourceChangeListenerCacheRefresher.refreshExpiredCachesAndNotifyListeners();
//cache should be invalidated for matching library name and version
- assertThat(myEvaluationSettings.getLibraryCache()).hasSize(6);
+ assertThat(myEvaluationSettings.getLibraryCache()).hasSize(7);
}
@Test
diff --git a/hapi-fhir-storage-mdm/pom.xml b/hapi-fhir-storage-mdm/pom.xml
index 6075061dc6a..7f6779287ec 100644
--- a/hapi-fhir-storage-mdm/pom.xml
+++ b/hapi-fhir-storage-mdm/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-storage-test-utilities/pom.xml b/hapi-fhir-storage-test-utilities/pom.xml
index db16c567f49..2496ea7f0ba 100644
--- a/hapi-fhir-storage-test-utilities/pom.xml
+++ b/hapi-fhir-storage-test-utilities/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-storage/pom.xml b/hapi-fhir-storage/pom.xml
index b20baf0c3d7..dbf8d1ced1d 100644
--- a/hapi-fhir-storage/pom.xml
+++ b/hapi-fhir-storage/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/dao/index/DaoResourceLinkResolver.java b/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/dao/index/DaoResourceLinkResolver.java
index e76ed2801bb..9434e126936 100644
--- a/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/dao/index/DaoResourceLinkResolver.java
+++ b/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/dao/index/DaoResourceLinkResolver.java
@@ -134,7 +134,7 @@ public class DaoResourceLinkResolver implements
type, targetReference, idPart, theRequest, theTransactionDetails);
if (!createdTableOpt.isPresent()) {
- if (myStorageSettings.isEnforceReferentialIntegrityOnWrite() == false) {
+ if (!myStorageSettings.isEnforceReferentialIntegrityOnWrite()) {
return null;
}
@@ -150,20 +150,8 @@ public class DaoResourceLinkResolver implements
"Resolved resource of type {} as PID: {}",
resolvedResource.getResourceType(),
resolvedResource.getPersistentId());
- if (!resourceType.equals(resolvedResource.getResourceType())) {
- ourLog.error(
- "Resource with PID {} was of type {} and wanted {}",
- resolvedResource.getPersistentId(),
- resourceType,
- resolvedResource.getResourceType());
- throw new UnprocessableEntityException(Msg.code(1095)
- + "Resource contains reference to unknown resource ID " + targetResourceId.getValue());
- }
-
- if (resolvedResource.getDeleted() != null) {
- String resName = resolvedResource.getResourceType();
- throw new InvalidRequestException(Msg.code(1096) + "Resource " + resName + "/" + idPart
- + " is deleted, specified in path: " + sourcePath);
+ if (!validateResolvedResourceOrThrow(resourceType, resolvedResource, targetResourceId, idPart, sourcePath)) {
+ return null;
}
if (persistentId == null) {
@@ -182,6 +170,45 @@ public class DaoResourceLinkResolver implements
return resolvedResource;
}
+ /**
+ * Validates the resolved resource.
+ * If 'Enforce Referential Integrity on Write' is enabled:
+ * Throws UnprocessableEntityException
when resource types do not match
+ * Throws InvalidRequestException
when the resolved resource was deleted
+ *
+ * Otherwise, return false when resource types do not match or resource was deleted
+ * and return true if the resolved resource is valid.
+ */
+ private boolean validateResolvedResourceOrThrow(
+ String resourceType,
+ IResourceLookup resolvedResource,
+ IIdType targetResourceId,
+ String idPart,
+ String sourcePath) {
+ if (!resourceType.equals(resolvedResource.getResourceType())) {
+ ourLog.error(
+ "Resource with PID {} was of type {} and wanted {}",
+ resolvedResource.getPersistentId(),
+ resourceType,
+ resolvedResource.getResourceType());
+ if (!myStorageSettings.isEnforceReferentialIntegrityOnWrite()) {
+ return false;
+ }
+ throw new UnprocessableEntityException(Msg.code(1095)
+ + "Resource contains reference to unknown resource ID " + targetResourceId.getValue());
+ }
+
+ if (resolvedResource.getDeleted() != null) {
+ if (!myStorageSettings.isEnforceReferentialIntegrityOnWrite()) {
+ return false;
+ }
+ String resName = resolvedResource.getResourceType();
+ throw new InvalidRequestException(Msg.code(1096) + "Resource " + resName + "/" + idPart
+ + " is deleted, specified in path: " + sourcePath);
+ }
+ return true;
+ }
+
@Nullable
@Override
public IBaseResource loadTargetResource(
diff --git a/hapi-fhir-structures-dstu2.1/pom.xml b/hapi-fhir-structures-dstu2.1/pom.xml
index ad65f33ad54..9b0b6862b32 100644
--- a/hapi-fhir-structures-dstu2.1/pom.xml
+++ b/hapi-fhir-structures-dstu2.1/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-structures-dstu2/pom.xml b/hapi-fhir-structures-dstu2/pom.xml
index 891eb98b319..718c23b5326 100644
--- a/hapi-fhir-structures-dstu2/pom.xml
+++ b/hapi-fhir-structures-dstu2/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-structures-dstu3/pom.xml b/hapi-fhir-structures-dstu3/pom.xml
index cf3ae30aba5..99473d8ea42 100644
--- a/hapi-fhir-structures-dstu3/pom.xml
+++ b/hapi-fhir-structures-dstu3/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-structures-hl7org-dstu2/pom.xml b/hapi-fhir-structures-hl7org-dstu2/pom.xml
index dc22111adef..c93237fa349 100644
--- a/hapi-fhir-structures-hl7org-dstu2/pom.xml
+++ b/hapi-fhir-structures-hl7org-dstu2/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-structures-r4/pom.xml b/hapi-fhir-structures-r4/pom.xml
index 612e2dcfb14..fa613174e8a 100644
--- a/hapi-fhir-structures-r4/pom.xml
+++ b/hapi-fhir-structures-r4/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-structures-r4b/pom.xml b/hapi-fhir-structures-r4b/pom.xml
index a810259a2c7..4eb3c7bd63b 100644
--- a/hapi-fhir-structures-r4b/pom.xml
+++ b/hapi-fhir-structures-r4b/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-structures-r5/pom.xml b/hapi-fhir-structures-r5/pom.xml
index a3c7f077788..10380569b8a 100644
--- a/hapi-fhir-structures-r5/pom.xml
+++ b/hapi-fhir-structures-r5/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-test-utilities/pom.xml b/hapi-fhir-test-utilities/pom.xml
index 23ef56c067d..f29a7f80edc 100644
--- a/hapi-fhir-test-utilities/pom.xml
+++ b/hapi-fhir-test-utilities/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-test-utilities/src/main/java/ca/uhn/fhir/test/utilities/RestServerR4Helper.java b/hapi-fhir-test-utilities/src/main/java/ca/uhn/fhir/test/utilities/RestServerR4Helper.java
index 5ac8aa67343..435d000939c 100644
--- a/hapi-fhir-test-utilities/src/main/java/ca/uhn/fhir/test/utilities/RestServerR4Helper.java
+++ b/hapi-fhir-test-utilities/src/main/java/ca/uhn/fhir/test/utilities/RestServerR4Helper.java
@@ -221,6 +221,28 @@ public class RestServerR4Helper extends BaseRestServerHelper implements BeforeEa
myRestServer.setConceptMapResourceProvider(theResourceProvider);
}
+ public HashMapResourceProvider getResourceProvider(Class theResourceType) {
+ @SuppressWarnings("unchecked")
+ HashMapResourceProvider resourceProvider = (HashMapResourceProvider) myRestServer.myResourceProvidersMap.get(theResourceType);
+ assert resourceProvider != null : "No resource provider defined for resource type: '" + theResourceType + "'" ;
+ return resourceProvider;
+ }
+
+ public void setResourceProvider(HashMapResourceProvider theResourceProvider) {
+ assert theResourceProvider.getResourceType() != null : "resourceProvider doesn't have a resourceType";
+ @SuppressWarnings("unchecked")
+ HashMapResourceProvider resourceProvider = (HashMapResourceProvider) myRestServer.myResourceProvidersMap.get(theResourceProvider.getResourceType());
+
+ if (resourceProvider != null) {
+ resourceProvider.getStoredResources().forEach(theResourceProvider::store);
+ myRestServer.unregisterProvider(resourceProvider);
+ }
+
+ registerProvider(theResourceProvider);
+ myRestServer.myResourceProvidersMap.put(theResourceProvider.getResourceType(), theResourceProvider);
+ }
+
+
public void setPagingProvider(IPagingProvider thePagingProvider) {
myPagingProvider = thePagingProvider;
}
@@ -295,6 +317,8 @@ public class RestServerR4Helper extends BaseRestServerHelper implements BeforeEa
private HashMapResourceProvider myConceptMapResourceProvider;
private RestServerDstu3Helper.MyPlainProvider myPlainProvider;
+ private final Map, HashMapResourceProvider>> myResourceProvidersMap = new HashMap<>();
+
private final boolean myInitialTransactionLatchEnabled;
private PagingHttpMethodEnum myPagingHttpMethod = PagingHttpMethodEnum.GET;
diff --git a/hapi-fhir-test-utilities/src/main/java/ca/uhn/fhir/test/utilities/server/HashMapResourceProviderExtension.java b/hapi-fhir-test-utilities/src/main/java/ca/uhn/fhir/test/utilities/server/HashMapResourceProviderExtension.java
index 47be1c0016f..5ed7c33677b 100644
--- a/hapi-fhir-test-utilities/src/main/java/ca/uhn/fhir/test/utilities/server/HashMapResourceProviderExtension.java
+++ b/hapi-fhir-test-utilities/src/main/java/ca/uhn/fhir/test/utilities/server/HashMapResourceProviderExtension.java
@@ -40,6 +40,7 @@ public class HashMapResourceProviderExtension extends H
private final RestfulServerExtension myRestfulServerExtension;
private boolean myClearBetweenTests = true;
+ private boolean myInitialized = false;
private final List myUpdates = new ArrayList<>();
/**
@@ -55,7 +56,9 @@ public class HashMapResourceProviderExtension extends H
@Override
public void afterEach(ExtensionContext context) throws Exception {
- myRestfulServerExtension.getRestfulServer().unregisterProvider(HashMapResourceProviderExtension.this);
+ if (myClearBetweenTests) {
+ myRestfulServerExtension.getRestfulServer().unregisterProvider(HashMapResourceProviderExtension.this);
+ }
}
@Override
@@ -77,8 +80,11 @@ public class HashMapResourceProviderExtension extends H
if (myClearBetweenTests) {
clear();
clearCounts();
+ myRestfulServerExtension.getRestfulServer().registerProvider(HashMapResourceProviderExtension.this);
+ } else if (!myInitialized) {
+ myInitialized = true;
+ myRestfulServerExtension.getRestfulServer().registerProvider(HashMapResourceProviderExtension.this);
}
- myRestfulServerExtension.getRestfulServer().registerProvider(HashMapResourceProviderExtension.this);
}
@Override
diff --git a/hapi-fhir-testpage-overlay/pom.xml b/hapi-fhir-testpage-overlay/pom.xml
index 86cb5491962..fca8cd4ec66 100644
--- a/hapi-fhir-testpage-overlay/pom.xml
+++ b/hapi-fhir-testpage-overlay/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../pom.xml
diff --git a/hapi-fhir-validation-resources-dstu2.1/pom.xml b/hapi-fhir-validation-resources-dstu2.1/pom.xml
index 39a50f70244..2e4c696ee12 100644
--- a/hapi-fhir-validation-resources-dstu2.1/pom.xml
+++ b/hapi-fhir-validation-resources-dstu2.1/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-validation-resources-dstu2/pom.xml b/hapi-fhir-validation-resources-dstu2/pom.xml
index 1cd6e7487ec..138e7289d27 100644
--- a/hapi-fhir-validation-resources-dstu2/pom.xml
+++ b/hapi-fhir-validation-resources-dstu2/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-validation-resources-dstu3/pom.xml b/hapi-fhir-validation-resources-dstu3/pom.xml
index f50bea30960..e0004b8c837 100644
--- a/hapi-fhir-validation-resources-dstu3/pom.xml
+++ b/hapi-fhir-validation-resources-dstu3/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-validation-resources-r4/pom.xml b/hapi-fhir-validation-resources-r4/pom.xml
index f0c88093297..c6ab551404a 100644
--- a/hapi-fhir-validation-resources-r4/pom.xml
+++ b/hapi-fhir-validation-resources-r4/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-validation-resources-r4b/pom.xml b/hapi-fhir-validation-resources-r4b/pom.xml
index 75b31d7a730..325d05648e8 100644
--- a/hapi-fhir-validation-resources-r4b/pom.xml
+++ b/hapi-fhir-validation-resources-r4b/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-validation-resources-r5/pom.xml b/hapi-fhir-validation-resources-r5/pom.xml
index 97ca30bf0c8..b853d0cc3ab 100644
--- a/hapi-fhir-validation-resources-r5/pom.xml
+++ b/hapi-fhir-validation-resources-r5/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-validation/pom.xml b/hapi-fhir-validation/pom.xml
index 64edc13bbe8..49d73daa1e0 100644
--- a/hapi-fhir-validation/pom.xml
+++ b/hapi-fhir-validation/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-tinder-plugin/pom.xml b/hapi-tinder-plugin/pom.xml
index 78c7469c56f..94029265a48 100644
--- a/hapi-tinder-plugin/pom.xml
+++ b/hapi-tinder-plugin/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../pom.xml
diff --git a/hapi-tinder-test/pom.xml b/hapi-tinder-test/pom.xml
index c8b8229c4ba..466e9d27784 100644
--- a/hapi-tinder-test/pom.xml
+++ b/hapi-tinder-test/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../pom.xml
diff --git a/pom.xml b/pom.xml
index 8aa11b301dd..481c3a77047 100644
--- a/pom.xml
+++ b/pom.xml
@@ -8,7 +8,7 @@
ca.uhn.hapi.fhir
hapi-fhir
pom
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
HAPI-FHIR
An open-source implementation of the FHIR specification in Java.
@@ -869,6 +869,7 @@
delopst
Primož Delopst
+ Better
Zach Smith
@@ -948,7 +949,7 @@
- 6.3.18
+ 6.3.23
2.41.1
-Dfile.encoding=UTF-8 -Xmx2048m
diff --git a/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml b/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml
index ed8ad2356a4..f69c2fd2d79 100644
--- a/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml
+++ b/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml
@@ -7,7 +7,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../../pom.xml
diff --git a/tests/hapi-fhir-base-test-mindeps-client/pom.xml b/tests/hapi-fhir-base-test-mindeps-client/pom.xml
index 7e5d062d647..991c29eff82 100644
--- a/tests/hapi-fhir-base-test-mindeps-client/pom.xml
+++ b/tests/hapi-fhir-base-test-mindeps-client/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../../pom.xml
diff --git a/tests/hapi-fhir-base-test-mindeps-server/pom.xml b/tests/hapi-fhir-base-test-mindeps-server/pom.xml
index 487e1f73df6..4e278702a42 100644
--- a/tests/hapi-fhir-base-test-mindeps-server/pom.xml
+++ b/tests/hapi-fhir-base-test-mindeps-server/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 7.5.0-SNAPSHOT
+ 7.5.1-SNAPSHOT
../../pom.xml