Compare commits

...

12 Commits

Author SHA1 Message Date
Martha Mitran 7b8c452d58
Merge 80519bf0c4 into 3f6d1eb29b 2024-09-26 10:43:18 -04:00
Thomas Papke 3f6d1eb29b
#5768 Upgrade to latest simple-java-mail (#6261) 2024-09-26 02:07:27 +00:00
Tadgh 377e44b6ca
attribution and pom change (#6309) 2024-09-25 20:38:22 +00:00
Martha Mitran 20d3e6bb25
Fix missing qualifier search for reference search parameters (#6306)
* Fix missing qualifier search for reference search parameter. Reuse tests and run them for both indexing enabled and disabled.

* Fix edge case where the search parameter has multiple paths. Add a test. Fix some of the compile warnings in a test class.

* Fix test setup.
2024-09-24 23:46:38 +00:00
Martha Mitran 80519bf0c4 Adding more tests for endpoint validation and repoitory validation with javascript configuration. Some changes in existing tests. 2024-01-12 08:28:46 -08:00
Martha Mitran d3b1d75dce Merge remote-tracking branch 'origin/master' into 5235-questions-on-fhir-resource-validation 2024-01-11 15:00:38 -08:00
Martha Mitran 3ccb548036 Merge remote-tracking branch 'origin/master' into 5235-questions-on-fhir-resource-validation 2024-01-09 14:57:08 -08:00
Martha Mitran 3885690716 More tests for search with profile and small changes in existing tests 2023-12-15 16:49:25 -08:00
Martha Mitran be1d3fac76 Add a few more tests with repository validation rules with profiles 2023-12-14 16:08:27 -08:00
Martha Mitran 5ed382228d Add test with multiple profiles 2023-12-14 10:57:51 -08:00
Martha Mitran 49d209823f Update tests to reflect questions 2023-12-13 16:10:23 -08:00
Martha Mitran 15497e39a9 Questions on FHIR Repository Validation and profile versions. 2023-12-13 15:58:14 -08:00
18 changed files with 1294 additions and 698 deletions

View File

@ -0,0 +1,5 @@
---
type: fix
issue: 6290
title: "Previously, a specific migration task was using the `TRIM()` function, which does not exist in MSSQL 2012. This was causing migrations targeting MSSQL 2012 to fail.
This has been corrected and replaced with usage of a combination of LTRIM() and RTRIM(). Thanks to Primož Delopst at Better for the contribution!"

View File

@ -0,0 +1,6 @@
---
type: fix
issue: 6305
title: "Previously, when having StorageSettings#getIndexMissingFields() == IndexEnabledEnum.DISABLED (default value)
and attempting to search with the missing qualifier against a resource type with multiple search parameters of type reference,
the returned results would be incorrect. This has been fixed."

View File

@ -800,14 +800,19 @@ public class ResourceLinkPredicateBuilder extends BaseJoiningPredicateBuilder im
subquery.addCustomColumns(1); subquery.addCustomColumns(1);
subquery.addFromTable(getTable()); subquery.addFromTable(getTable());
String resourceType = theParams.getResourceTablePredicateBuilder().getResourceType();
RuntimeSearchParam paramDefinition =
mySearchParamRegistry.getRuntimeSearchParam(resourceType, theParams.getParamName());
List<String> pathList = paramDefinition.getPathsSplitForResourceType(resourceType);
Condition subQueryCondition = ComboCondition.and( Condition subQueryCondition = ComboCondition.and(
BinaryCondition.equalTo( BinaryCondition.equalTo(
getResourceIdColumn(), getResourceIdColumn(),
theParams.getResourceTablePredicateBuilder().getResourceIdColumn()), theParams.getResourceTablePredicateBuilder().getResourceIdColumn()),
BinaryCondition.equalTo( BinaryCondition.equalTo(getResourceTypeColumn(), generatePlaceholder(resourceType)),
getResourceTypeColumn(), ComboCondition.or(pathList.stream()
generatePlaceholder( .map(path -> BinaryCondition.equalTo(getColumnSourcePath(), generatePlaceholder(path)))
theParams.getResourceTablePredicateBuilder().getResourceType()))); .toArray(BinaryCondition[]::new)));
subquery.addCondition(subQueryCondition); subquery.addCondition(subQueryCondition);

View File

@ -70,6 +70,11 @@
<artifactId>jakarta.servlet-api</artifactId> <artifactId>jakarta.servlet-api</artifactId>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency>
<groupId>jakarta.mail</groupId>
<artifactId>jakarta.mail-api</artifactId>
<optional>true</optional>
</dependency>
<!-- test dependencies --> <!-- test dependencies -->
<dependency> <dependency>

View File

@ -28,8 +28,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import javax.mail.internet.InternetAddress; import jakarta.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage; import jakarta.mail.internet.MimeMessage;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;

View File

@ -17,8 +17,8 @@ import org.junit.jupiter.api.extension.RegisterExtension;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import javax.mail.internet.InternetAddress; import jakarta.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage; import jakarta.mail.internet.MimeMessage;
import java.util.Arrays; import java.util.Arrays;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;

View File

@ -26,8 +26,8 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.api.extension.RegisterExtension;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import javax.mail.internet.InternetAddress; import jakarta.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage; import jakarta.mail.internet.MimeMessage;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;

View File

@ -1,9 +1,10 @@
package ca.uhn.fhir.jpa.dao.r4; 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.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.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.test.BaseJpaR4Test; import ca.uhn.fhir.jpa.test.BaseJpaR4Test;
import ca.uhn.fhir.rest.api.server.IBundleProvider; 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.ReferenceParam;
import ca.uhn.fhir.rest.param.StringParam; import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.param.TokenParam; 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.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.DateType; import org.hl7.fhir.r4.model.DateType;
import org.hl7.fhir.r4.model.DecimalType; import org.hl7.fhir.r4.model.DecimalType;
@ -26,57 +26,25 @@ import org.hl7.fhir.r4.model.Reference;
import org.hl7.fhir.r4.model.Task; import org.hl7.fhir.r4.model.Task;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test { public class FhirResourceDaoR4SearchMissingTest {
private static final Logger ourLog = LoggerFactory.getLogger(FhirResourceDaoR4SearchMissingTest.class);
@Nested
class IndexMissingDisabledTests extends MissingTests {
@BeforeEach @BeforeEach
public void beforeResetMissing() { public void before() {
myStorageSettings.setIndexMissingFields(JpaStorageSettings.IndexEnabledEnum.ENABLED); myStorageSettings.setIndexMissingFields(StorageSettings.IndexEnabledEnum.DISABLED);
}
@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());
}
}
@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 @Test
public void testIndexMissingFieldsDisabledDontCreateIndexes() { public void testIndexMissingFieldsDisabledDontCreateIndexes() {
myStorageSettings.setIndexMissingFields(JpaStorageSettings.IndexEnabledEnum.DISABLED);
Organization org = new Organization(); Organization org = new Organization();
org.setActive(true); org.setActive(true);
myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless(); myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless();
@ -93,8 +61,6 @@ public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test {
@Test @Test
public void testIndexMissingFieldsDisabledDontCreateIndexesWithNormalizedQuantitySearchSupported() { public void testIndexMissingFieldsDisabledDontCreateIndexesWithNormalizedQuantitySearchSupported() {
myStorageSettings.setIndexMissingFields(JpaStorageSettings.IndexEnabledEnum.DISABLED);
myStorageSettings.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED); myStorageSettings.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED);
Organization org = new Organization(); Organization org = new Organization();
org.setActive(true); org.setActive(true);
@ -112,8 +78,6 @@ public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test {
@Test @Test
public void testIndexMissingFieldsDisabledDontCreateIndexesWithNormalizedQuantityStorageSupported() { public void testIndexMissingFieldsDisabledDontCreateIndexesWithNormalizedQuantityStorageSupported() {
myStorageSettings.setIndexMissingFields(JpaStorageSettings.IndexEnabledEnum.DISABLED);
myStorageSettings.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_STORAGE_SUPPORTED); myStorageSettings.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_STORAGE_SUPPORTED);
Organization org = new Organization(); Organization org = new Organization();
org.setActive(true); org.setActive(true);
@ -128,6 +92,15 @@ public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test {
}); });
} }
}
@Nested
class IndexMissingEnabledTests extends MissingTests {
@BeforeEach
public void before() {
myStorageSettings.setIndexMissingFields(StorageSettings.IndexEnabledEnum.ENABLED);
}
@SuppressWarnings("unused") @SuppressWarnings("unused")
@Test @Test
@ -144,11 +117,10 @@ public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test {
task.setRequester(new Reference(oid1)); task.setRequester(new Reference(oid1));
tid1 = myTaskDao.create(task, mySrd).getId().toUnqualifiedVersionless(); tid1 = myTaskDao.create(task, mySrd).getId().toUnqualifiedVersionless();
} }
IIdType tid2;
{ {
Task task = new Task(); Task task = new Task();
task.setOwner(new Reference(oid1)); task.setOwner(new Reference(oid1));
tid2 = myTaskDao.create(task, mySrd).getId().toUnqualifiedVersionless(); myTaskDao.create(task, mySrd).getId().toUnqualifiedVersionless();
} }
IIdType oid2; IIdType oid2;
@ -170,27 +142,36 @@ public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test {
map = new SearchParameterMap(); map = new SearchParameterMap();
map.add(Organization.SP_NAME, new StringParam().setMissing(true)); map.add(Organization.SP_NAME, new StringParam().setMissing(true));
ids = toUnqualifiedVersionlessIds(myOrganizationDao.search(map)); ids = toUnqualifiedVersionlessIds(myOrganizationDao.search(map, mySrd));
assertThat(ids).containsExactly(oid1); assertThat(ids).containsExactly(oid1);
ourLog.info("Starting Search 2"); ourLog.info("Starting Search 2");
map = new SearchParameterMap(); map = new SearchParameterMap();
map.add(Task.SP_REQUESTER, new ReferenceParam("Organization", "name:missing", "true")); map.add(Task.SP_REQUESTER, new ReferenceParam("Organization", "name:missing", "true"));
ids = toUnqualifiedVersionlessIds(myTaskDao.search(map)); ids = toUnqualifiedVersionlessIds(myTaskDao.search(map, mySrd));
assertThat(ids).containsExactly(tid1); // NOT tid2 assertThat(ids).containsExactly(tid1); // NOT tid2
map = new SearchParameterMap(); map = new SearchParameterMap();
map.add(Task.SP_REQUESTER, new ReferenceParam("Organization", "name:missing", "false")); map.add(Task.SP_REQUESTER, new ReferenceParam("Organization", "name:missing", "false"));
ids = toUnqualifiedVersionlessIds(myTaskDao.search(map)); ids = toUnqualifiedVersionlessIds(myTaskDao.search(map, mySrd));
assertThat(ids).containsExactly(tid3); assertThat(ids).containsExactly(tid3);
map = new SearchParameterMap(); map = new SearchParameterMap();
map.add(Patient.SP_ORGANIZATION, new ReferenceParam("Organization", "name:missing", "true")); map.add(Patient.SP_ORGANIZATION, new ReferenceParam("Organization", "name:missing", "true"));
ids = toUnqualifiedVersionlessIds(myPatientDao.search(map)); ids = toUnqualifiedVersionlessIds(myPatientDao.search(map, mySrd));
assertThat(ids).isEmpty(); assertThat(ids).isEmpty();
} }
}
static class MissingTests extends BaseJpaR4Test {
@AfterEach
public void after() {
myStorageSettings.setIndexMissingFields(new StorageSettings().getIndexMissingFields());
myStorageSettings.setNormalizedQuantitySearchLevel(new StorageSettings().getNormalizedQuantitySearchLevel());
}
@Test @Test
public void testSearchWithMissingDate() { public void testSearchWithMissingDate() {
@ -217,7 +198,7 @@ public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test {
DateParam param = new DateParam(); DateParam param = new DateParam();
param.setMissing(false); param.setMissing(false);
params.add(Patient.SP_BIRTHDATE, param); params.add(Patient.SP_BIRTHDATE, param);
List<IIdType> patients = toUnqualifiedVersionlessIds(myPatientDao.search(params)); List<IIdType> patients = toUnqualifiedVersionlessIds(myPatientDao.search(params, mySrd));
assertThat(patients).containsSubsequence(notMissing); assertThat(patients).containsSubsequence(notMissing);
assertThat(patients).doesNotContainSubsequence(missing); assertThat(patients).doesNotContainSubsequence(missing);
} }
@ -227,7 +208,7 @@ public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test {
DateParam param = new DateParam(); DateParam param = new DateParam();
param.setMissing(true); param.setMissing(true);
params.add(Patient.SP_BIRTHDATE, param); params.add(Patient.SP_BIRTHDATE, param);
List<IIdType> patients = toUnqualifiedVersionlessIds(myPatientDao.search(params)); List<IIdType> patients = toUnqualifiedVersionlessIds(myPatientDao.search(params, mySrd));
assertThat(patients).containsSubsequence(missing); assertThat(patients).containsSubsequence(missing);
assertThat(patients).doesNotContainSubsequence(notMissing); assertThat(patients).doesNotContainSubsequence(notMissing);
} }
@ -238,9 +219,11 @@ public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test {
String locId = myLocationDao.create(new Location(), mySrd).getId().toUnqualifiedVersionless().getValue(); 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(); String locId2 = myLocationDao.create(new Location().setPosition(new Location.LocationPositionComponent(new DecimalType(10), new DecimalType(10))), mySrd).getId().toUnqualifiedVersionless().getValue();
runInTransaction(() -> { runInTransaction(() -> ourLog.info("Coords:\n * {}",
ourLog.info("Coords:\n * {}", myResourceIndexedSearchParamCoordsDao.findAll().stream().map(t -> t.toString()).collect(Collectors.joining("\n * "))); myResourceIndexedSearchParamCoordsDao.findAll().stream()
}); .map(ResourceIndexedSearchParamCoords::toString).collect(Collectors.joining("\n * "))
)
);
{ {
SearchParameterMap params = new SearchParameterMap(); SearchParameterMap params = new SearchParameterMap();
@ -249,7 +232,7 @@ public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test {
param.setMissing(true); param.setMissing(true);
params.add(Location.SP_NEAR, param); params.add(Location.SP_NEAR, param);
myCaptureQueriesListener.clear(); myCaptureQueriesListener.clear();
List<String> patients = toUnqualifiedVersionlessIdValues(myLocationDao.search(params)); List<String> patients = toUnqualifiedVersionlessIdValues(myLocationDao.search(params, mySrd));
myCaptureQueriesListener.logSelectQueriesForCurrentThread(0); myCaptureQueriesListener.logSelectQueriesForCurrentThread(0);
assertThat(patients).containsSubsequence(locId); assertThat(patients).containsSubsequence(locId);
assertThat(patients).doesNotContainSubsequence(locId2); assertThat(patients).doesNotContainSubsequence(locId2);
@ -260,7 +243,7 @@ public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test {
TokenParam param = new TokenParam(); TokenParam param = new TokenParam();
param.setMissing(false); param.setMissing(false);
params.add(Location.SP_NEAR, param); params.add(Location.SP_NEAR, param);
List<String> patients = toUnqualifiedVersionlessIdValues(myLocationDao.search(params)); List<String> patients = toUnqualifiedVersionlessIdValues(myLocationDao.search(params, mySrd));
assertThat(patients).containsSubsequence(locId2); assertThat(patients).containsSubsequence(locId2);
assertThat(patients).doesNotContainSubsequence(locId); assertThat(patients).doesNotContainSubsequence(locId);
} }
@ -271,15 +254,15 @@ public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test {
MedicationRequest mr1 = new MedicationRequest(); MedicationRequest mr1 = new MedicationRequest();
mr1.addCategory().addCoding().setSystem("urn:medicationroute").setCode("oral"); mr1.addCategory().addCoding().setSystem("urn:medicationroute").setCode("oral");
mr1.addDosageInstruction().getTiming().addEventElement().setValueAsString("2017-01-01"); mr1.addDosageInstruction().getTiming().addEventElement().setValueAsString("2017-01-01");
IIdType id1 = myMedicationRequestDao.create(mr1).getId().toUnqualifiedVersionless(); myMedicationRequestDao.create(mr1, mySrd).getId().toUnqualifiedVersionless();
MedicationRequest mr2 = new MedicationRequest(); MedicationRequest mr2 = new MedicationRequest();
mr2.addCategory().addCoding().setSystem("urn:medicationroute").setCode("oral"); mr2.addCategory().addCoding().setSystem("urn:medicationroute").setCode("oral");
IIdType id2 = myMedicationRequestDao.create(mr2).getId().toUnqualifiedVersionless(); IIdType id2 = myMedicationRequestDao.create(mr2, mySrd).getId().toUnqualifiedVersionless();
SearchParameterMap map = new SearchParameterMap(); SearchParameterMap map = new SearchParameterMap();
map.add(MedicationRequest.SP_DATE, new DateParam().setMissing(true)); map.add(MedicationRequest.SP_DATE, new DateParam().setMissing(true));
IBundleProvider results = myMedicationRequestDao.search(map); IBundleProvider results = myMedicationRequestDao.search(map, mySrd);
List<String> ids = toUnqualifiedVersionlessIdValues(results); List<String> ids = toUnqualifiedVersionlessIdValues(results);
assertThat(ids).containsExactly(id2.getValue()); assertThat(ids).containsExactly(id2.getValue());
@ -308,7 +291,7 @@ public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test {
QuantityParam param = new QuantityParam(); QuantityParam param = new QuantityParam();
param.setMissing(false); param.setMissing(false);
params.add(Observation.SP_VALUE_QUANTITY, param); params.add(Observation.SP_VALUE_QUANTITY, param);
List<IIdType> patients = toUnqualifiedVersionlessIds(myObservationDao.search(params)); List<IIdType> patients = toUnqualifiedVersionlessIds(myObservationDao.search(params, mySrd));
assertThat(patients).doesNotContainSubsequence(missing); assertThat(patients).doesNotContainSubsequence(missing);
assertThat(patients).containsSubsequence(notMissing); assertThat(patients).containsSubsequence(notMissing);
} }
@ -318,7 +301,7 @@ public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test {
QuantityParam param = new QuantityParam(); QuantityParam param = new QuantityParam();
param.setMissing(true); param.setMissing(true);
params.add(Observation.SP_VALUE_QUANTITY, param); params.add(Observation.SP_VALUE_QUANTITY, param);
List<IIdType> patients = toUnqualifiedVersionlessIds(myObservationDao.search(params)); List<IIdType> patients = toUnqualifiedVersionlessIds(myObservationDao.search(params, mySrd));
assertThat(patients).containsSubsequence(missing); assertThat(patients).containsSubsequence(missing);
assertThat(patients).doesNotContainSubsequence(notMissing); assertThat(patients).doesNotContainSubsequence(notMissing);
} }
@ -343,8 +326,16 @@ public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test {
} }
runInTransaction(() -> { 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("Quantity Indexes:\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 * "))); 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 // Quantity Param
@ -354,7 +345,7 @@ public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test {
QuantityParam param = new QuantityParam(); QuantityParam param = new QuantityParam();
param.setMissing(false); param.setMissing(false);
params.add(Observation.SP_VALUE_QUANTITY, param); params.add(Observation.SP_VALUE_QUANTITY, param);
List<IIdType> patients = toUnqualifiedVersionlessIds(myObservationDao.search(params)); List<IIdType> patients = toUnqualifiedVersionlessIds(myObservationDao.search(params, mySrd));
assertThat(patients).doesNotContainSubsequence(missing); assertThat(patients).doesNotContainSubsequence(missing);
assertThat(patients).containsSubsequence(notMissing); assertThat(patients).containsSubsequence(notMissing);
} }
@ -365,7 +356,7 @@ public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test {
param.setMissing(true); param.setMissing(true);
params.add(Observation.SP_VALUE_QUANTITY, param); params.add(Observation.SP_VALUE_QUANTITY, param);
myCaptureQueriesListener.clear(); myCaptureQueriesListener.clear();
List<IIdType> patients = toUnqualifiedVersionlessIds(myObservationDao.search(params)); List<IIdType> patients = toUnqualifiedVersionlessIds(myObservationDao.search(params, mySrd));
myCaptureQueriesListener.logSelectQueries(); myCaptureQueriesListener.logSelectQueries();
assertThat(patients).containsSubsequence(missing); assertThat(patients).containsSubsequence(missing);
assertThat(patients).doesNotContainSubsequence(notMissing); assertThat(patients).doesNotContainSubsequence(notMissing);
@ -397,7 +388,7 @@ public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test {
QuantityParam param = new QuantityParam(); QuantityParam param = new QuantityParam();
param.setMissing(false); param.setMissing(false);
params.add(Observation.SP_VALUE_QUANTITY, param); params.add(Observation.SP_VALUE_QUANTITY, param);
List<IIdType> patients = toUnqualifiedVersionlessIds(myObservationDao.search(params)); List<IIdType> patients = toUnqualifiedVersionlessIds(myObservationDao.search(params, mySrd));
assertThat(patients).doesNotContainSubsequence(missing); assertThat(patients).doesNotContainSubsequence(missing);
assertThat(patients).containsSubsequence(notMissing); assertThat(patients).containsSubsequence(notMissing);
} }
@ -407,7 +398,7 @@ public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test {
QuantityParam param = new QuantityParam(); QuantityParam param = new QuantityParam();
param.setMissing(true); param.setMissing(true);
params.add(Observation.SP_VALUE_QUANTITY, param); params.add(Observation.SP_VALUE_QUANTITY, param);
List<IIdType> patients = toUnqualifiedVersionlessIds(myObservationDao.search(params)); List<IIdType> patients = toUnqualifiedVersionlessIds(myObservationDao.search(params, mySrd));
assertThat(patients).containsSubsequence(missing); assertThat(patients).containsSubsequence(missing);
assertThat(patients).doesNotContainSubsequence(notMissing); assertThat(patients).doesNotContainSubsequence(notMissing);
} }
@ -440,7 +431,7 @@ public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test {
ReferenceParam param = new ReferenceParam(); ReferenceParam param = new ReferenceParam();
param.setMissing(false); param.setMissing(false);
params.add(Patient.SP_ORGANIZATION, param); params.add(Patient.SP_ORGANIZATION, param);
List<IIdType> patients = toUnqualifiedVersionlessIds(myPatientDao.search(params)); List<IIdType> patients = toUnqualifiedVersionlessIds(myPatientDao.search(params, mySrd));
assertThat(patients).doesNotContainSubsequence(missing); assertThat(patients).doesNotContainSubsequence(missing);
assertThat(patients).containsSubsequence(notMissing); assertThat(patients).containsSubsequence(notMissing);
} }
@ -450,13 +441,36 @@ public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test {
ReferenceParam param = new ReferenceParam(); ReferenceParam param = new ReferenceParam();
param.setMissing(true); param.setMissing(true);
params.add(Patient.SP_ORGANIZATION, param); params.add(Patient.SP_ORGANIZATION, param);
List<IIdType> patients = toUnqualifiedVersionlessIds(myPatientDao.search(params)); List<IIdType> patients = toUnqualifiedVersionlessIds(myPatientDao.search(params, mySrd));
assertThat(patients).containsSubsequence(missing); assertThat(patients).containsSubsequence(missing);
assertThat(patients).doesNotContainSubsequence(notMissing); assertThat(patients).doesNotContainSubsequence(notMissing);
assertThat(patients).doesNotContainSubsequence(orgId); assertThat(patients).doesNotContainSubsequence(orgId);
} }
} }
@Test
public void testSearchWithMissingReference_resourceTypeWithMultipleReferences() {
IIdType patientId = createPatient();
IIdType observationId = createObservation(withSubject(patientId));
SearchParameterMap params = new SearchParameterMap();
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.add(Observation.SP_ENCOUNTER, new ReferenceParam().setMissing(true));
IBundleProvider bundleProvider = myObservationDao.search(params, mySrd);
assertThat(bundleProvider.getAllResourceIds()).isEmpty();
}
@Test @Test
public void testSearchWithMissingString() { public void testSearchWithMissingString() {
IIdType orgId = myOrganizationDao.create(new Organization(), mySrd).getId(); IIdType orgId = myOrganizationDao.create(new Organization(), mySrd).getId();
@ -482,7 +496,7 @@ public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test {
StringParam param = new StringParam(); StringParam param = new StringParam();
param.setMissing(false); param.setMissing(false);
params.add(Patient.SP_FAMILY, param); params.add(Patient.SP_FAMILY, param);
List<IIdType> patients = toUnqualifiedVersionlessIds(myPatientDao.search(params)); List<IIdType> patients = toUnqualifiedVersionlessIds(myPatientDao.search(params, mySrd));
assertThat(patients).doesNotContainSubsequence(missing); assertThat(patients).doesNotContainSubsequence(missing);
assertThat(patients).containsSubsequence(notMissing); assertThat(patients).containsSubsequence(notMissing);
} }
@ -492,7 +506,7 @@ public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test {
StringParam param = new StringParam(); StringParam param = new StringParam();
param.setMissing(true); param.setMissing(true);
params.add(Patient.SP_FAMILY, param); params.add(Patient.SP_FAMILY, param);
List<IIdType> patients = toUnqualifiedVersionlessIds(myPatientDao.search(params)); List<IIdType> patients = toUnqualifiedVersionlessIds(myPatientDao.search(params, mySrd));
assertThat(patients).containsSubsequence(missing); assertThat(patients).containsSubsequence(missing);
assertThat(patients).doesNotContainSubsequence(notMissing); assertThat(patients).doesNotContainSubsequence(notMissing);
} }
@ -520,7 +534,7 @@ public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test {
TokenParam param = new TokenParam(); TokenParam param = new TokenParam();
param.setMissing(false); param.setMissing(false);
params.add(Observation.SP_CODE, param); params.add(Observation.SP_CODE, param);
List<IIdType> patients = toUnqualifiedVersionlessIds(myObservationDao.search(params)); List<IIdType> patients = toUnqualifiedVersionlessIds(myObservationDao.search(params, mySrd));
assertThat(patients).doesNotContainSubsequence(missing); assertThat(patients).doesNotContainSubsequence(missing);
assertThat(patients).containsSubsequence(notMissing); assertThat(patients).containsSubsequence(notMissing);
} }
@ -530,10 +544,11 @@ public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test {
TokenParam param = new TokenParam(); TokenParam param = new TokenParam();
param.setMissing(true); param.setMissing(true);
params.add(Observation.SP_CODE, param); params.add(Observation.SP_CODE, param);
List<IIdType> patients = toUnqualifiedVersionlessIds(myObservationDao.search(params)); List<IIdType> patients = toUnqualifiedVersionlessIds(myObservationDao.search(params, mySrd));
assertThat(patients).containsSubsequence(missing); assertThat(patients).containsSubsequence(missing);
assertThat(patients).doesNotContainSubsequence(notMissing); assertThat(patients).doesNotContainSubsequence(notMissing);
} }
} }
}
} }

View File

@ -217,7 +217,7 @@ import static org.mockito.Mockito.when;
public class ResourceProviderR4Test extends BaseResourceProviderR4Test { public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResourceProviderR4Test.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResourceProviderR4Test.class);
private SearchCoordinatorSvcImpl mySearchCoordinatorSvcRaw; private SearchCoordinatorSvcImpl mySearchCoordinatorSvcRaw;
private CapturingInterceptor myCapturingInterceptor = new CapturingInterceptor(); private final CapturingInterceptor myCapturingInterceptor = new CapturingInterceptor();
@Autowired @Autowired
private ISearchDao mySearchEntityDao; private ISearchDao mySearchEntityDao;
@ -413,15 +413,15 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
Patient pt1 = new Patient(); Patient pt1 = new Patient();
pt1.addName().setFamily("Elizabeth"); 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(); Patient pt2 = new Patient();
pt2.addName().setFamily("fghijk"); 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(); Patient pt3 = new Patient();
pt3.addName().setFamily("zzzzz"); pt3.addName().setFamily("zzzzz");
myPatientDao.create(pt3).getId().toUnqualifiedVersionless().getValue(); myPatientDao.create(pt3, mySrd).getId().toUnqualifiedVersionless().getValue();
Bundle output = myClient Bundle output = myClient
@ -450,7 +450,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
Patient pt1 = new Patient(); Patient pt1 = new Patient();
pt1.addName().setFamily("Smith%"); pt1.addName().setFamily("Smith%");
String pt1id = myPatientDao.create(pt1).getId().toUnqualifiedVersionless().getValue(); String pt1id = myPatientDao.create(pt1, mySrd).getId().toUnqualifiedVersionless().getValue();
Bundle output = myClient Bundle output = myClient
.search() .search()
@ -463,7 +463,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
Patient pt2 = new Patient(); Patient pt2 = new Patient();
pt2.addName().setFamily("Sm%ith"); pt2.addName().setFamily("Sm%ith");
String pt2id = myPatientDao.create(pt2).getId().toUnqualifiedVersionless().getValue(); String pt2id = myPatientDao.create(pt2, mySrd).getId().toUnqualifiedVersionless().getValue();
output = myClient output = myClient
.search() .search()
@ -740,7 +740,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
Patient p = new Patient(); Patient p = new Patient();
p.addName().setFamily("FAM").addGiven("GIV"); 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(); myClient.read().resource("Patient").withId(id.toUnqualifiedVersionless()).execute();
@ -763,7 +763,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
Patient p = new Patient(); Patient p = new Patient();
p.addName().setFamily("FAM").addGiven("GIV"); p.addName().setFamily("FAM").addGiven("GIV");
IIdType id = myPatientDao.create(p).getId().toUnqualifiedVersionless(); IIdType id = myPatientDao.create(p, mySrd).getId().toUnqualifiedVersionless();
myClient myClient
.delete() .delete()
@ -1025,57 +1025,58 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
public void testCreateAndReadBackResourceWithContainedReferenceToContainer() { public void testCreateAndReadBackResourceWithContainedReferenceToContainer() {
myFhirContext.setParserErrorHandler(new StrictErrorHandler()); myFhirContext.setParserErrorHandler(new StrictErrorHandler());
String input = "{\n" + String input = """
" \"resourceType\": \"Organization\",\n" + {
" \"id\": \"1\",\n" + "resourceType": "Organization",
" \"meta\": {\n" + "id": "1",
" \"tag\": [\n" + "meta": {
" {\n" + "tag": [
" \"system\": \"https://blah.org/deployment\",\n" + {
" \"code\": \"e69414dd-b5c2-462d-bcfd-9d04d6b16596\",\n" + "system": "https://blah.org/deployment",
" \"display\": \"DEPLOYMENT\"\n" + "code": "e69414dd-b5c2-462d-bcfd-9d04d6b16596",
" },\n" + "display": "DEPLOYMENT"
" {\n" + },
" \"system\": \"https://blah.org/region\",\n" + {
" \"code\": \"b47d7a5b-b159-4bed-a8f8-3258e6603adb\",\n" + "system": "https://blah.org/region",
" \"display\": \"REGION\"\n" + "code": "b47d7a5b-b159-4bed-a8f8-3258e6603adb",
" },\n" + "display": "REGION"
" {\n" + },
" \"system\": \"https://blah.org/provider\",\n" + {
" \"code\": \"28c30004-0333-40cf-9e7f-3f9e080930bd\",\n" + "system": "https://blah.org/provider",
" \"display\": \"PROVIDER\"\n" + "code": "28c30004-0333-40cf-9e7f-3f9e080930bd",
" }\n" + "display": "PROVIDER"
" ]\n" + }
" },\n" + ]
" \"contained\": [\n" + },
" {\n" + "contained": [
" \"resourceType\": \"Location\",\n" + {
" \"id\": \"2\",\n" + "resourceType": "Location",
" \"position\": {\n" + "id": "2",
" \"longitude\": 51.443238301454289,\n" + "position": {
" \"latitude\": 7.34196905697293\n" + "longitude": 51.443238301454289,
" },\n" + "latitude": 7.34196905697293
" \"managingOrganization\": {\n" + },
" \"reference\": \"#\"\n" + "managingOrganization": {
" }\n" + "reference": "#"
" }\n" + }
" ],\n" + }
" \"type\": [\n" + ],
" {\n" + "type": [
" \"coding\": [\n" + {
" {\n" + "coding": [
" \"system\": \"https://blah.org/fmc/OrganizationType\",\n" + {
" \"code\": \"CLINIC\",\n" + "system": "https://blah.org/fmc/OrganizationType",
" \"display\": \"Clinic\"\n" + "code": "CLINIC",
" }\n" + "display": "Clinic"
" ]\n" + }
" }\n" + ]
" ],\n" + }
" \"name\": \"testOrg\"\n" + ],
"}"; "name": "testOrg"
}""";
Organization org = myFhirContext.newJsonParser().parseResource(Organization.class, input); 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); org = myOrganizationDao.read(id);
String output = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(org); String output = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(org);
@ -1095,9 +1096,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
} }
List<IBaseResource> outcome = myClient.transaction().withResources(resources).prettyPrint().encodedXml().execute(); List<IBaseResource> outcome = myClient.transaction().withResources(resources).prettyPrint().encodedXml().execute();
runInTransaction(() -> { runInTransaction(() -> assertEquals(100, myResourceTableDao.count()));
assertEquals(100, myResourceTableDao.count());
});
Bundle found = myClient Bundle found = myClient
.search() .search()
@ -1306,7 +1305,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
} }
@Test @Test
public void testCreateQuestionnaireResponseWithValidation() throws IOException { public void testCreateQuestionnaireResponseWithValidation() {
CodeSystem cs = new CodeSystem(); CodeSystem cs = new CodeSystem();
cs.setUrl("http://cs"); cs.setUrl("http://cs");
cs.setStatus(Enumerations.PublicationStatus.ACTIVE); 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.. * 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(); Socket sock = new Socket();
try (sock) {
sock.setSoTimeout(3000); sock.setSoTimeout(3000);
try {
sock.connect(new InetSocketAddress("localhost", myPort)); 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(("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)); 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())); BufferedReader socketInput = new BufferedReader(new InputStreamReader(sock.getInputStream()));
// String response = "";
StringBuilder b = new StringBuilder(); StringBuilder b = new StringBuilder();
char[] buf = new char[1000]; char[] buf = new char[1000];
while (socketInput.read(buf) != -1) { while (socketInput.read(buf) != -1) {
@ -1925,9 +1923,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
ourLog.debug("Resp: {}", resp); ourLog.debug("Resp: {}", resp);
} catch (SocketTimeoutException e) { } catch (SocketTimeoutException e) {
e.printStackTrace(); ourLog.debug(e.getMessage(), e);
} finally {
sock.close();
} }
Thread.sleep(1000); Thread.sleep(1000);
@ -2398,7 +2394,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
assertThat(idValues).as(idValues.toString()).hasSize(10); assertThat(idValues).as(idValues.toString()).hasSize(10);
idValues = searchAndReturnUnqualifiedIdValues(myServerBase + "/_history?_at=gt" + InstantDt.withCurrentTime().getYear()); 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); 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()); assertEquals(1, history.getEntry().size());
BundleEntryComponent historyEntry0 = history.getEntry().get(0); BundleEntryComponent historyEntry0 = history.getEntry().get(0);
// validate entry.fullUrl // validate entry.fullUrl
@ -2476,7 +2472,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
myMemoryCacheService.invalidateCaches(MemoryCacheService.CacheEnum.PID_TO_FORCED_ID); 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()); assertEquals(1, history.getEntry().size());
BundleEntryComponent historyEntry0 = history.getEntry().get(0); BundleEntryComponent historyEntry0 = history.getEntry().get(0);
// validate entry.fullUrl // validate entry.fullUrl
@ -2508,7 +2504,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
ourLog.info("Res ID: {}", id); 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); assertThat(history.getEntry()).hasSize(3);
assertEquals(id.withVersion("3").getValue(), history.getEntry().get(0).getResource().getId()); assertEquals(id.withVersion("3").getValue(), history.getEntry().get(0).getResource().getId());
assertThat(((Patient) history.getEntry().get(0).getResource()).getName()).hasSize(1); assertThat(((Patient) history.getEntry().get(0).getResource()).getName()).hasSize(1);
@ -2746,7 +2742,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
int total = 20; int total = 20;
Organization org = new Organization(); Organization org = new Organization();
org.setName("ORG"); org.setName("ORG");
IIdType orgId = myOrganizationDao.create(org).getId().toUnqualifiedVersionless(); IIdType orgId = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless();
Coding tagCode = new Coding(); Coding tagCode = new Coding();
tagCode.setCode("test"); tagCode.setCode("test");
@ -2757,7 +2753,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
.addTag(tagCode); .addTag(tagCode);
t.setStatus(Task.TaskStatus.REQUESTED); t.setStatus(Task.TaskStatus.REQUESTED);
t.getOwner().setReference(orgId.getValue()); t.getOwner().setReference(orgId.getValue());
myTaskDao.create(t); myTaskDao.create(t, mySrd);
} }
HashSet<String> ids = new HashSet<>(); HashSet<String> ids = new HashSet<>();
@ -2835,12 +2831,12 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
if (orgCount > 0) { if (orgCount > 0) {
Organization org = new Organization(); Organization org = new Organization();
org.setName("ORG"); org.setName("ORG");
IIdType orgId = myOrganizationDao.create(org).getId().toUnqualifiedVersionless(); IIdType orgId = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless();
orgCount--; orgCount--;
t.getOwner().setReference(orgId.getValue()); t.getOwner().setReference(orgId.getValue());
} }
myTaskDao.create(t); myTaskDao.create(t, mySrd);
} }
} }
@ -2909,12 +2905,12 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
if (orgCount > 0) { if (orgCount > 0) {
Organization org = new Organization(); Organization org = new Organization();
org.setName("ORG"); org.setName("ORG");
IIdType orgId = myOrganizationDao.create(org).getId().toUnqualifiedVersionless(); IIdType orgId = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless();
orgCount--; orgCount--;
t.getOwner().setReference(orgId.getValue()); t.getOwner().setReference(orgId.getValue());
} }
myTaskDao.create(t); myTaskDao.create(t, mySrd);
} }
} }
@ -2961,13 +2957,13 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
public void testIncludeCountDoesntIncludeIncludes() { public void testIncludeCountDoesntIncludeIncludes() {
Organization org = new Organization(); Organization org = new Organization();
org.setName("ORG"); 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++) { for (int i = 0; i < 10; i++) {
Patient pt = new Patient(); Patient pt = new Patient();
pt.getManagingOrganization().setReference(orgId.getValue()); pt.getManagingOrganization().setReference(orgId.getValue());
pt.addName().setFamily("FAM" + i); pt.addName().setFamily("FAM" + i);
myPatientDao.create(pt); myPatientDao.create(pt, mySrd);
} }
Bundle bundle = myClient Bundle bundle = myClient
@ -3168,7 +3164,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
Patient newPt = myClient.read().resource(Patient.class).withId(pid1.getIdPart()).execute(); Patient newPt = myClient.read().resource(Patient.class).withId(pid1.getIdPart()).execute();
assertEquals("2", newPt.getIdElement().getVersionIdPart()); assertEquals("2", newPt.getIdElement().getVersionIdPart());
assertEquals(false, newPt.getActive()); assertFalse(newPt.getActive());
} }
@Test @Test
@ -3196,7 +3192,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
Patient newPt = myClient.read().resource(Patient.class).withId(pid1.getIdPart()).execute(); Patient newPt = myClient.read().resource(Patient.class).withId(pid1.getIdPart()).execute();
assertEquals("1", newPt.getIdElement().getVersionIdPart()); assertEquals("1", newPt.getIdElement().getVersionIdPart());
assertEquals(true, newPt.getActive()); assertTrue(newPt.getActive());
} }
@Test @Test
@ -3226,7 +3222,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
Patient newPt = myClient.read().resource(Patient.class).withId(pid1.getIdPart()).execute(); Patient newPt = myClient.read().resource(Patient.class).withId(pid1.getIdPart()).execute();
assertEquals("2", newPt.getIdElement().getVersionIdPart()); assertEquals("2", newPt.getIdElement().getVersionIdPart());
assertEquals(false, newPt.getActive()); assertFalse(newPt.getActive());
} }
@Test @Test
@ -3255,7 +3251,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
Patient newPt = myClient.read().resource(Patient.class).withId(pid1.getIdPart()).execute(); Patient newPt = myClient.read().resource(Patient.class).withId(pid1.getIdPart()).execute();
assertEquals("2", newPt.getIdElement().getVersionIdPart()); assertEquals("2", newPt.getIdElement().getVersionIdPart());
assertEquals(false, newPt.getActive()); assertFalse(newPt.getActive());
} }
@Test @Test
@ -3323,12 +3319,12 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
{ {
Bundle returned = myClient.search().forResource(Patient.class).encodedXml().returnBundle(Bundle.class).execute(); 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()); assertEquals(BundleType.SEARCHSET, returned.getType());
} }
{ {
Bundle returned = myClient.search().forResource(Patient.class).encodedJson().returnBundle(Bundle.class).execute(); 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()); assertEquals(1, bundle.getTotal());
assertThat(bundle.getEntry()).hasSize(1); assertThat(bundle.getEntry()).hasSize(1);
assertEquals(id2.getIdPart(), bundle.getEntry().get(0).getResource().getIdElement().getIdPart()); 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("\"B\"");
assertThat(text).doesNotContain("\"B1\""); 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 @Test
@ -3873,9 +3860,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
p.addName().setFamily(methodName + "1"); p.addName().setFamily(methodName + "1");
IIdType pid1 = myClient.create().resource(p).execute().getId().toUnqualifiedVersionless(); IIdType pid1 = myClient.create().resource(p).execute().getId().toUnqualifiedVersionless();
Thread.sleep(10);
long time1 = System.currentTimeMillis(); long time1 = System.currentTimeMillis();
Thread.sleep(10);
Patient p2 = new Patient(); Patient p2 = new Patient();
p2.addName().setFamily(methodName + "2"); p2.addName().setFamily(methodName + "2");
@ -4064,9 +4049,6 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
public void testSearchLastUpdatedParamRp() throws InterruptedException { public void testSearchLastUpdatedParamRp() throws InterruptedException {
String methodName = "testSearchLastUpdatedParamRp"; String methodName = "testSearchLastUpdatedParamRp";
int sleep = 100;
Thread.sleep(sleep);
DateTimeType beforeAny = new DateTimeType(new Date(), TemporalPrecisionEnum.MILLI); DateTimeType beforeAny = new DateTimeType(new Date(), TemporalPrecisionEnum.MILLI);
IIdType id1a; IIdType id1a;
{ {
@ -4083,9 +4065,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
id1b = myClient.create().resource(patient).execute().getId().toUnqualifiedVersionless(); id1b = myClient.create().resource(patient).execute().getId().toUnqualifiedVersionless();
} }
Thread.sleep(1100);
DateTimeType beforeR2 = new DateTimeType(new Date(), TemporalPrecisionEnum.MILLI); DateTimeType beforeR2 = new DateTimeType(new Date(), TemporalPrecisionEnum.MILLI);
Thread.sleep(1100);
IIdType id2; IIdType id2;
{ {
@ -4249,13 +4229,12 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
Bundle bundle = myFhirContext.newXmlParser().parseResource(Bundle.class, resp); Bundle bundle = myFhirContext.newXmlParser().parseResource(Bundle.class, resp);
matches = bundle.getEntry().size(); matches = bundle.getEntry().size();
assertThat(matches).isGreaterThan(0); assertThat(matches).isPositive();
} }
@Test @Test
public void testSearchReturnsSearchDate() throws Exception { public void testSearchReturnsSearchDate() throws Exception {
Date before = new Date(); Date before = new Date();
Thread.sleep(1);
//@formatter:off //@formatter:off
Bundle found = myClient Bundle found = myClient
@ -4266,7 +4245,6 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
.execute(); .execute();
//@formatter:on //@formatter:on
Thread.sleep(1);
Date after = new Date(); Date after = new Date();
InstantType updated = found.getMeta().getLastUpdatedElement(); InstantType updated = found.getMeta().getLastUpdatedElement();
@ -4300,7 +4278,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
myObservationDao.create(obs, mySrd); 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); 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); 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); myObservationDao.create(obs, mySrd);
ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
} }
// > 1m // > 1m
String uri = myServerBase + "/Observation?code-value-quantity=http://" + UrlUtil.escapeUrlParam("loinc.org|2345-7$gt1|http://unitsofmeasure.org|m"); 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<String> ids = searchAndReturnUnqualifiedVersionlessIdValues(uri); List<String> ids = searchAndReturnUnqualifiedVersionlessIdValues(uri);
assertThat(ids).hasSize(3); assertThat(ids).hasSize(3);
//>= 100cm //>= 100cm
uri = myServerBase + "/Observation?code-value-quantity=http://" + UrlUtil.escapeUrlParam("loinc.org|2345-7$gt100|http://unitsofmeasure.org|cm"); 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); ids = searchAndReturnUnqualifiedVersionlessIdValues(uri);
assertThat(ids).hasSize(3); assertThat(ids).hasSize(3);
//>= 10dm //>= 10dm
uri = myServerBase + "/Observation?code-value-quantity=http://" + UrlUtil.escapeUrlParam("loinc.org|2345-7$gt10|http://unitsofmeasure.org|dm"); 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); ids = searchAndReturnUnqualifiedVersionlessIdValues(uri);
assertThat(ids).hasSize(3); assertThat(ids).hasSize(3);
} }
@ -4381,7 +4359,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
myObservationDao.create(obs, mySrd); 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); 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); 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); 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; String uri;
@ -4451,7 +4429,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
myObservationDao.create(obs, mySrd); 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); 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); 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(); myCaptureQueriesListener.clear();
@ -4490,8 +4468,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
//-- check use normalized quantity table to search //-- check use normalized quantity table to search
String searchSql = myCaptureQueriesListener.getSelectQueries().get(0).getSql(true, true); String searchSql = myCaptureQueriesListener.getSelectQueries().get(0).getSql(true, true);
assertThat(searchSql).doesNotContain("HFJ_SPIDX_QUANTITY t0"); assertThat(searchSql).doesNotContain("HFJ_SPIDX_QUANTITY t0").contains("HFJ_SPIDX_QUANTITY_NRML");
assertThat(searchSql).contains("HFJ_SPIDX_QUANTITY_NRML");
} }
@Test @Test
@ -5044,7 +5021,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
oid1 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless(); 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(); 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(); 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(); 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"; String uri = myServerBase + "/Observation?_sort=code-value-quantity";
@ -5092,7 +5069,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
found = myFhirContext.newXmlParser().parseResource(Bundle.class, output); 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<IIdType> list = toUnqualifiedVersionlessIds(found); List<IIdType> list = toUnqualifiedVersionlessIds(found);
assertThat(found.getEntry()).hasSize(4); assertThat(found.getEntry()).hasSize(4);
@ -5129,7 +5106,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
oid1 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless(); 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(); 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(); 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)); comp.setValue(new Quantity().setValue(250));
oid4 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless(); 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"; 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); 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<IIdType> list = toUnqualifiedVersionlessIds(found); List<IIdType> list = toUnqualifiedVersionlessIds(found);
assertThat(found.getEntry()).hasSize(4); assertThat(found.getEntry()).hasSize(4);
@ -5264,9 +5241,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
List<IIdType> list = toUnqualifiedVersionlessIds(found); List<IIdType> list = toUnqualifiedVersionlessIds(found);
ourLog.info(methodName + " found: " + list.toString() + " - Wanted " + orgMissing + " but not " + orgNotMissing); ourLog.info(methodName + " found: " + list.toString() + " - Wanted " + orgMissing + " but not " + orgNotMissing);
assertThat(list).doesNotContain(orgNotMissing); assertThat(list).doesNotContain(orgNotMissing).doesNotContain(deletedIdMissingTrue).contains(orgMissing);
assertThat(list).doesNotContain(deletedIdMissingTrue);
assertThat(list).contains(orgMissing);
} }
@Test @Test
@ -5927,7 +5902,6 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
} }
Date before = new Date(); Date before = new Date();
Thread.sleep(100);
pt = new Patient(); pt = new Patient();
pt.setId(id.getIdPart()); pt.setId(id.getIdPart());
@ -6450,7 +6424,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
cc.addCoding().setCode("2345-7").setSystem("http://loinc.org"); 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")); 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(); 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"); 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")); 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); myObservationDao.update(obs, mySrd);
} }
@ -6479,7 +6453,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
myObservationDao.create(obs, mySrd); 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); 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); myObservationDao.create(obs, mySrd);
ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
} }
// > 1m // > 1m
String uri = myServerBase + "/Observation?code-value-quantity=http://" + UrlUtil.escapeUrlParam("loinc.org|2345-7$gt1|http://unitsofmeasure.org|m"); 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<String> ids = searchAndReturnUnqualifiedVersionlessIdValues(uri); List<String> ids = searchAndReturnUnqualifiedVersionlessIdValues(uri);
assertThat(ids).hasSize(2); assertThat(ids).hasSize(2);
//>= 100cm //>= 100cm
uri = myServerBase + "/Observation?code-value-quantity=http://" + UrlUtil.escapeUrlParam("loinc.org|2345-7$gt100|http://unitsofmeasure.org|cm"); 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); ids = searchAndReturnUnqualifiedVersionlessIdValues(uri);
assertThat(ids).hasSize(2); assertThat(ids).hasSize(2);
//>= 10dm //>= 10dm
uri = myServerBase + "/Observation?code-value-quantity=http://" + UrlUtil.escapeUrlParam("loinc.org|2345-7$gt10|http://unitsofmeasure.org|dm"); 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); ids = searchAndReturnUnqualifiedVersionlessIdValues(uri);
assertThat(ids).hasSize(2); assertThat(ids).hasSize(2);
} }
@ -6540,7 +6514,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
patient.setBirthDateElement(new DateType("2073")); patient.setBirthDateElement(new DateType("2073"));
pid0 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless(); 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); ourLog.info("pid0 " + pid0);
} }
@ -6553,7 +6527,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
String resp = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8); String resp = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
ourLog.info(resp); ourLog.info(resp);
Bundle bundle = myFhirContext.newXmlParser().parseResource(Bundle.class, 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"; 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); String resp = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
ourLog.info(resp); ourLog.info(resp);
Bundle bundle = myFhirContext.newXmlParser().parseResource(Bundle.class, 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.IsEnforceRefOnType
&& theInput.IsEnforceRefOnWrite).isFalse(); && theInput.IsEnforceRefOnWrite).isFalse();
} catch (InvalidRequestException ex) { } catch (InvalidRequestException ex) {
assertThat(ex.getMessage().contains( assertThat(ex.getMessage()).as(ex.getMessage()).contains("Invalid resource reference");
"Invalid resource reference"
)).as(ex.getMessage()).isTrue();
} finally { } finally {
myStorageSettings.setEnforceReferentialIntegrityOnWrite(isEnforceRefOnWrite); myStorageSettings.setEnforceReferentialIntegrityOnWrite(isEnforceRefOnWrite);
myStorageSettings.setEnforceReferenceTargetTypes(isEnforceRefTargetTypes); myStorageSettings.setEnforceReferenceTargetTypes(isEnforceRefTargetTypes);
@ -7331,9 +7303,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
patient.setBirthDate(cal.getTime()); patient.setBirthDate(cal.getTime());
} }
return patient; return patient;
}, (isMissing) -> { }, (isMissing) -> doSearch(Patient.class, Patient.BIRTHDATE.isMissing(isMissing)));
return doSearch(Patient.class, Patient.BIRTHDATE.isMissing(isMissing));
});
} }
@ParameterizedTest @ParameterizedTest
@ -7346,9 +7316,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
patient.setGender(AdministrativeGender.FEMALE); patient.setGender(AdministrativeGender.FEMALE);
} }
return patient; return patient;
}, isMissing -> { }, isMissing -> doSearch(Patient.class, Patient.GENDER.isMissing(isMissing)));
return doSearch(Patient.class, Patient.GENDER.isMissing(isMissing));
});
} }
@ParameterizedTest @ParameterizedTest
@ -7364,9 +7332,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
patient.setGeneralPractitioner(Collections.singletonList(new Reference(practitionerId))); patient.setGeneralPractitioner(Collections.singletonList(new Reference(practitionerId)));
} }
return patient; return patient;
}, isMissing -> { }, isMissing -> doSearch(Patient.class, Patient.GENERAL_PRACTITIONER.isMissing(isMissing)));
return doSearch(Patient.class, Patient.GENERAL_PRACTITIONER.isMissing(isMissing));
});
} }
@ParameterizedTest @ParameterizedTest
@ -7409,9 +7375,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
sp.setUrl("http://example.com"); sp.setUrl("http://example.com");
} }
return sp; return sp;
}, isMissing -> { }, isMissing -> doSearch(SearchParameter.class, SearchParameter.URL.isMissing(isMissing)));
return doSearch(SearchParameter.class, SearchParameter.URL.isMissing(isMissing));
});
} }
@ParameterizedTest @ParameterizedTest
@ -7424,9 +7388,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
obs.setValue(new Quantity(3)); obs.setValue(new Quantity(3));
} }
return obs; return obs;
}, isMissing -> { }, isMissing -> doSearch(Observation.class, Observation.VALUE_QUANTITY.isMissing(isMissing)));
return doSearch(Observation.class, Observation.VALUE_QUANTITY.isMissing(isMissing));
});
} }
@ParameterizedTest @ParameterizedTest
@ -7457,7 +7419,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
Y doTask(X theInput); Y doTask(X theInput);
} }
private static class MissingSearchTestParameters { public static class MissingSearchTestParameters {
/** /**
* The setting for IndexMissingFields * The setting for IndexMissingFields
*/ */

View File

@ -0,0 +1,171 @@
package ca.uhn.fhir.jpa.validation;
import ca.uhn.fhir.context.support.DefaultProfileValidationSupport;
import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome;
import ca.uhn.fhir.jpa.provider.BaseResourceProviderR4Test;
import ca.uhn.fhir.rest.api.server.SystemRequestDetails;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor;
import ca.uhn.fhir.validation.ResultSeverityEnum;
import org.hl7.fhir.common.hapi.validation.support.CachingValidationSupport;
import org.hl7.fhir.common.hapi.validation.support.CommonCodeSystemsTerminologyService;
import org.hl7.fhir.common.hapi.validation.support.InMemoryTerminologyServerValidationSupport;
import org.hl7.fhir.common.hapi.validation.support.PrePopulatedValidationSupport;
import org.hl7.fhir.common.hapi.validation.support.SnapshotGeneratingValidationSupport;
import org.hl7.fhir.common.hapi.validation.support.ValidationSupportChain;
import org.hl7.fhir.common.hapi.validation.validator.FhirInstanceValidator;
import org.hl7.fhir.r4.model.Meta;
import org.hl7.fhir.r4.model.Patient;
import org.hl7.fhir.r4.model.StructureDefinition;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import javax.annotation.Nonnull;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.fail;
public class EndpointResourceValidationR4Test extends BaseResourceProviderR4Test {
private static final String myResourceType = "Patient";
private final String myProfile = "http://example.org/fhir/StructureDefinition/TestPatient";
private PrePopulatedValidationSupport myPrePopulatedValidationSupport;
@BeforeEach
public void before() {
CachingValidationSupport myValidationSupport = createCachingValidationSupport();
FhirInstanceValidator fhirInstanceValidator = new FhirInstanceValidator(myValidationSupport);
RequestValidatingInterceptor interceptor = new RequestValidatingInterceptor();
interceptor.addValidatorModule(fhirInstanceValidator);
interceptor.setFailOnSeverity(ResultSeverityEnum.ERROR);
interceptor.setAddResponseHeaderOnSeverity(ResultSeverityEnum.INFORMATION);
myServer.registerInterceptor(interceptor);
}
@Nonnull
private CachingValidationSupport createCachingValidationSupport() {
myPrePopulatedValidationSupport = new PrePopulatedValidationSupport(myFhirContext);
ValidationSupportChain chain = new ValidationSupportChain(
new DefaultProfileValidationSupport(myFhirContext),
new SnapshotGeneratingValidationSupport(myFhirContext),
new CommonCodeSystemsTerminologyService(myFhirContext),
new InMemoryTerminologyServerValidationSupport(myFhirContext),
myPrePopulatedValidationSupport);
return new CachingValidationSupport(chain, true);
}
@Test
public void testCreatePatientRequest_withProfileNotRegistered_unknownProfile() {
createProfile(myProfile, "1", "Patient.identifier");
final Patient patient = new Patient();
patient.setMeta(new Meta().addProfile(myProfile));
try {
myClient.create().resource(patient).execute();
fail();
} catch (UnprocessableEntityException e) {
assertEquals("HTTP 422 Unprocessable Entity: Profile reference '" + myProfile + "' has not been checked because it is unknown", e.getMessage());
}
}
@Test
public void testCreatePatientRequest_withProfileNoVersion_throwsExceptionWithLatestVersion() {
createAndRegisterProfile("1", "Patient.identifier");
createAndRegisterProfile("2", "Patient.name");
final Patient patient = new Patient();
patient.setMeta(new Meta().addProfile(myProfile));
try {
myClient.create().resource(patient).execute();
fail();
} catch (UnprocessableEntityException e) {
assertEquals("HTTP 422 Unprocessable Entity: Patient.name: minimum required = 1, but only found 0 (from " + myProfile + "|2)", e.getMessage());
}
}
@Test
public void testCreatePatientRequest_withProfileWithVersion_throwsExceptionWithSpecifiedVersion() {
createAndRegisterProfile("1", "Patient.identifier");
createAndRegisterProfile("2", "Patient.name");
final Patient patient = new Patient();
patient.setMeta(new Meta().addProfile(myProfile + "|1"));
try {
myClient.create().resource(patient).execute();
fail();
} catch (UnprocessableEntityException e) {
assertEquals("HTTP 422 Unprocessable Entity: Patient.identifier: minimum required = 1, but only found 0 (from " + myProfile + "|1)", e.getMessage());
}
}
@Test
public void testCreatePatientRequest_withMultipleProfiles_throwsExceptionWithFirstDeclaredProfile() {
final String sdIdentifier = myProfile + "-identifier";
final String sdName = myProfile + "-name";
createAndRegisterProfile(sdIdentifier, "1", "Patient.identifier");
createAndRegisterProfile(sdName, "1", "Patient.name");
final Patient patient = new Patient();
patient.setMeta(new Meta().addProfile(sdIdentifier).addProfile(sdName));
try {
myClient.create().resource(patient).execute();
fail();
} catch (UnprocessableEntityException e) {
assertEquals("HTTP 422 Unprocessable Entity: Patient.identifier: minimum required = 1, but only found 0 (from " + sdIdentifier + "|1)", e.getMessage());
}
}
@Test
public void testCreatePatientRequest_withMultipleVersions_throwsExceptionWithFirstDeclaredProfile() {
createAndRegisterProfile(myProfile, "1", "Patient.identifier");
createAndRegisterProfile(myProfile, "2", "Patient.name");
createAndRegisterProfile(myProfile, "3", "Patient.birthDate");
final Patient patient = new Patient();
patient.setMeta(new Meta()
.addProfile(myProfile + "|2")
.addProfile(myProfile + "|1")
.addProfile(myProfile + "|3"));
try {
myClient.create().resource(patient).execute();
fail();
} catch (UnprocessableEntityException e) {
assertEquals("HTTP 422 Unprocessable Entity: Patient.name: minimum required = 1, but only found 0 (from " + myProfile + "|2)", e.getMessage());
}
}
private void createAndRegisterProfile(String theVersion, String thePath) {
createAndRegisterProfile(myProfile, theVersion, thePath);
}
private void createAndRegisterProfile(String theUrl, String theVersion, String thePath) {
StructureDefinition sd = createProfile(theUrl, theVersion, thePath);
myPrePopulatedValidationSupport.addStructureDefinition(sd);
}
private StructureDefinition createProfile(String theUrl, String theVersion, String thePath) {
final String baseProfile = "http://hl7.org/fhir/StructureDefinition/Patient";
final String profileId = "TestProfile";
StructureDefinition sd = new StructureDefinition()
.setUrl(theUrl).setVersion(theVersion)
.setBaseDefinition(baseProfile)
.setType(myResourceType)
.setDerivation(StructureDefinition.TypeDerivationRule.CONSTRAINT);
sd.setId(profileId);
sd.getDifferential().addElement()
.setPath(thePath)
.setMin(1)
.setId(thePath);
DaoMethodOutcome outcome = myStructureDefinitionDao.update(sd, new SystemRequestDetails());
assertNotNull(outcome.getResource());
return (StructureDefinition) outcome.getResource();
}
}

View File

@ -0,0 +1,180 @@
package ca.uhn.fhir.jpa.validation;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.support.DefaultProfileValidationSupport;
import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome;
import ca.uhn.fhir.jpa.provider.BaseResourceProviderR4Test;
import ca.uhn.fhir.validation.FhirValidator;
import ca.uhn.fhir.validation.SingleValidationMessage;
import ca.uhn.fhir.validation.ValidationResult;
import org.hl7.fhir.common.hapi.validation.support.CachingValidationSupport;
import org.hl7.fhir.common.hapi.validation.support.CommonCodeSystemsTerminologyService;
import org.hl7.fhir.common.hapi.validation.support.InMemoryTerminologyServerValidationSupport;
import org.hl7.fhir.common.hapi.validation.support.PrePopulatedValidationSupport;
import org.hl7.fhir.common.hapi.validation.support.SnapshotGeneratingValidationSupport;
import org.hl7.fhir.common.hapi.validation.support.ValidationSupportChain;
import org.hl7.fhir.common.hapi.validation.validator.FhirInstanceValidator;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.Patient;
import org.hl7.fhir.r4.model.StructureDefinition;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.Iterator;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
public class OnDemandResourceValidationR4Test extends BaseResourceProviderR4Test {
private static final FhirContext ourCtx = FhirContext.forR4();
private static final String myResourceType = "Patient";
private final String myProfile = "http://example.org/fhir/StructureDefinition/TestPatient";
@Test
public void testCreateStructureDefinition_createMultipleWithWithSameUrl_isStoredSuccessfully() {
createProfile("1", "Patient.identifier");
createProfile("2", "Patient.name");
createProfile("3", "Patient.birthdate");
}
private static FhirValidator myFhirValidator;
private static PrePopulatedValidationSupport ourValidationSupport;
@BeforeEach
public void before() {
myFhirValidator = ourCtx.newValidator();
myFhirValidator.setValidateAgainstStandardSchema(false);
myFhirValidator.setValidateAgainstStandardSchematron(false);
ourValidationSupport = new PrePopulatedValidationSupport(ourCtx);
ValidationSupportChain chain = new ValidationSupportChain(
new DefaultProfileValidationSupport(ourCtx),
new SnapshotGeneratingValidationSupport(ourCtx),
new CommonCodeSystemsTerminologyService(ourCtx),
new InMemoryTerminologyServerValidationSupport(ourCtx),
ourValidationSupport);
CachingValidationSupport myValidationSupport = new CachingValidationSupport(chain, true);
FhirInstanceValidator myInstanceVal = new FhirInstanceValidator(myValidationSupport);
myFhirValidator.registerValidatorModule(myInstanceVal);
}
@Test
public void testValidatePatient_withProfileNotRegistered_unknownProfile() {
createProfile(myProfile, "1", "Patient.identifier");
IIdType idType = createPatient(withProfile(myProfile));
Patient patient = myPatientDao.read(idType, mySrd);
ValidationResult validationResult = myFhirValidator.validateWithResult(patient);
assertFalse(validationResult.isSuccessful());
assertEquals(1, validationResult.getMessages().size());
SingleValidationMessage message = validationResult.getMessages().iterator().next();
assertEquals("Profile reference '" + myProfile + "' has not been checked because it is unknown", message.getMessage());
}
@Test
public void testValidatePatient_withProfileNoVersion_shouldUsesLatestVersion() {
createAndRegisterProfile(myProfile, "1", "Patient.identifier");
createAndRegisterProfile(myProfile, "2", "Patient.name");
IIdType idType = createPatient(withProfile(myProfile));
Patient patient = myPatientDao.read(idType, mySrd);
ValidationResult validationResult = myFhirValidator.validateWithResult(patient);
assertFalse(validationResult.isSuccessful());
assertEquals(1, validationResult.getMessages().size());
SingleValidationMessage message = validationResult.getMessages().iterator().next();
assertEquals("Patient.name: minimum required = 1, but only found 0 (from " + myProfile + "|2)", message.getMessage());
}
@Test
public void testValidatePatient_withProfileWithVersion_shouldUseSpecifiedVersion() {
createAndRegisterProfile(myProfile, "1", "Patient.identifier");
createAndRegisterProfile(myProfile, "2", "Patient.name");
IIdType idType = createPatient(withProfile(myProfile + "|1"));
Patient patient = myPatientDao.read(idType, mySrd);
ValidationResult validationResult = myFhirValidator.validateWithResult(patient);
assertFalse(validationResult.isSuccessful());
assertEquals(1, validationResult.getMessages().size());
SingleValidationMessage message = validationResult.getMessages().iterator().next();
assertEquals("Patient.identifier: minimum required = 1, but only found 0 (from " + myProfile + "|1)", message.getMessage());
}
@Test
public void testValidatePatient_withMultipleProfiles_validatesAgainstAllProfiles() {
final String sdIdentifier = myProfile + "-identifier";
final String sdName = myProfile + "-name";
createAndRegisterProfile(sdIdentifier, "1", "Patient.identifier");
createAndRegisterProfile(sdName, "1", "Patient.name");
IIdType idType = createPatient(withProfile(sdIdentifier), withProfile(sdName));
Patient patient = myPatientDao.read(idType, mySrd);
ValidationResult validationResult = myFhirValidator.validateWithResult(patient);
assertFalse(validationResult.isSuccessful());
assertEquals(2, validationResult.getMessages().size());
Iterator<SingleValidationMessage> messageIterator = validationResult.getMessages().iterator();
assertEquals("Patient.identifier: minimum required = 1, but only found 0 (from " + myProfile + "-identifier|1)", messageIterator.next().getMessage());
assertEquals("Patient.name: minimum required = 1, but only found 0 (from " + myProfile + "-name|1)", messageIterator.next().getMessage());
}
@Test
public void testValidatePatient_withMultipleVersions_validatesAgainstFirstVersion() {
createAndRegisterProfile(myProfile, "1", "Patient.identifier");
createAndRegisterProfile(myProfile, "2", "Patient.name");
createAndRegisterProfile(myProfile, "3", "Patient.birthDate");
IIdType idType = createPatient(
withProfile(myProfile + "|2"),
withProfile(myProfile + "|1"),
withProfile(myProfile + "|3"));
Patient patient = myPatientDao.read(idType, mySrd);
ValidationResult validationResult = myFhirValidator.validateWithResult(patient);
assertFalse(validationResult.isSuccessful());
assertEquals(1, validationResult.getMessages().size());
SingleValidationMessage message = validationResult.getMessages().iterator().next();
assertEquals("Patient.identifier: minimum required = 1, but only found 0 (from " + myProfile + "|1)", message.getMessage());
}
private void createAndRegisterProfile(String theUrl, String theVersion, String thePath) {
StructureDefinition sd = createProfile(theUrl, theVersion, thePath);
ourValidationSupport.addStructureDefinition(sd);
}
private void createProfile(String theVersion, String theRequiredPath) {
createProfile(myProfile, theVersion, theRequiredPath);
}
private StructureDefinition createProfile(String theUrl, String theVersion, String theRequiredPath) {
final String myResourceTypeDefinition = "http://hl7.org/fhir/StructureDefinition/Patient";
final String myProfileId = "TestProfile";
StructureDefinition sd = new StructureDefinition()
.setUrl(theUrl).setVersion(theVersion)
.setBaseDefinition(myResourceTypeDefinition)
.setType(myResourceType)
.setDerivation(StructureDefinition.TypeDerivationRule.CONSTRAINT);
sd.setId(myProfileId);
sd.getDifferential().addElement()
.setPath(theRequiredPath)
.setMin(1)
.setId(theRequiredPath);
DaoMethodOutcome outcome = myStructureDefinitionDao.update(sd, mySrd);
assertNotNull(outcome.getResource());
return (StructureDefinition) outcome.getResource();
}
}

View File

@ -0,0 +1,153 @@
package ca.uhn.fhir.jpa.validation;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome;
import ca.uhn.fhir.jpa.interceptor.validation.IRepositoryValidatingRule;
import ca.uhn.fhir.jpa.interceptor.validation.RepositoryValidatingInterceptor;
import ca.uhn.fhir.jpa.interceptor.validation.RepositoryValidatingRuleBuilder;
import ca.uhn.fhir.jpa.provider.BaseResourceProviderR4Test;
import ca.uhn.fhir.rest.api.server.SystemRequestDetails;
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
import org.hl7.fhir.r4.model.StructureDefinition;
import org.hl7.fhir.r5.utils.validation.constants.BestPracticeWarningLevel;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.Collections;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.fail;
public class RepositoryValidationOnCreateResourceR4Test extends BaseResourceProviderR4Test {
private static final String myResourceType = "Patient";
private final String myProfile = "http://example.org/fhir/StructureDefinition/TestPatient";
private static final FhirContext ourCtx = FhirContext.forR4();
private final RepositoryValidatingInterceptor myRepositoryValidatingInterceptor = new RepositoryValidatingInterceptor(ourCtx, Collections.emptyList());
@BeforeEach
public void before() {
myInterceptorRegistry.registerInterceptor(myRepositoryValidatingInterceptor);
}
@AfterEach
public void after() {
myInterceptorRegistry.unregisterInterceptor(myRepositoryValidatingInterceptor);
}
@Test
public void testCreatePatient_withValidationRuleNoVersion_validatesAgainstLatestVersion() {
createProfile("1", "Patient.identifier");
createProfile("2", "Patient.name");
setupRepositoryValidationRules(myProfile);
try {
createPatient(withProfile(myProfile));
fail();
} catch (PreconditionFailedException e) {
assertEquals(Msg.code(574)
+ "Patient.name: minimum required = 1, but only found 0 (from " + myProfile + "|2)", e.getMessage());
}
}
@Test
public void testCreatePatient_withValidationRuleWithVersion_unknownProfile() {
createProfile("1", "Patient.identifier");
createProfile("2", "Patient.name");
setupRepositoryValidationRules(myProfile + "|1");
try {
createPatient(withProfile(myProfile + "|1"));
fail();
} catch (PreconditionFailedException e) {
assertEquals(Msg.code(574) + "Profile reference '" + myProfile
+ "|1' has not been checked because it is unknown, and the validator is set to not fetch unknown profiles", e.getMessage());
}
}
@Test
public void testCreatePatient_withProfileWithVersion_doesNotConform() {
setupRepositoryValidationRules(myProfile);
try {
createPatient(withProfile(myProfile + "|1"));
fail();
} catch (PreconditionFailedException e) {
assertEquals(Msg.code(575) + "Resource of type \"" + myResourceType
+ "\" does not declare conformance to profile from: [" + myProfile + "]", e.getMessage());
}
}
@Test
public void testCreatePatient_withValidationRuleWithVersion_doesNotConform() {
setupRepositoryValidationRules(myProfile + "|1");
try {
createPatient(withProfile(myProfile));
fail();
} catch (PreconditionFailedException e) {
assertEquals(Msg.code(575) + "Resource of type \"" + myResourceType
+ "\" does not declare conformance to profile from: [" + myProfile + "|1]", e.getMessage());
}
}
@Test
public void testCreatePatient_withMultipleProfiles_validatesAgainstLastProfile() {
final String sdIdentifier = myProfile + "-identifier";
final String sdName = myProfile + "-name";
createProfile(sdIdentifier, "1", "Patient.identifier");
createProfile(sdName, "1", "Patient.name");
setupRepositoryValidationRules(sdIdentifier, sdName);
try {
createPatient(withProfile(sdIdentifier), withProfile(sdName));
fail();
} catch (PreconditionFailedException e) {
assertEquals(Msg.code(574)
+ "Patient.name: minimum required = 1, but only found 0 (from " + sdName + "|1)", e.getMessage());
}
}
private void setupRepositoryValidationRules(String... theProfiles) {
List<IRepositoryValidatingRule> rules = myAppCtx
.getBean(RepositoryValidatingRuleBuilder.REPOSITORY_VALIDATING_RULE_BUILDER, RepositoryValidatingRuleBuilder.class)
.forResourcesOfType(myResourceType)
.requireAtLeastOneProfileOf(theProfiles)
.and()
.requireValidationToDeclaredProfiles()
.withBestPracticeWarningLevel(BestPracticeWarningLevel.Ignore)
.rejectOnSeverity("error")
.build();
myRepositoryValidatingInterceptor.setRules(rules);
}
private void createProfile(String theVersion, String theRequiredPath) {
createProfile(myProfile, theVersion, theRequiredPath);
}
private void createProfile(String theUrl, String theVersion, String thePath) {
final String baseProfile = "http://hl7.org/fhir/StructureDefinition/Patient";
final String profileId = "TestProfile";
StructureDefinition sd = new StructureDefinition()
.setUrl(theUrl).setVersion(theVersion)
.setBaseDefinition(baseProfile)
.setType(myResourceType)
.setDerivation(StructureDefinition.TypeDerivationRule.CONSTRAINT);
sd.setId(profileId);
sd.getDifferential().addElement()
.setPath(thePath)
.setMin(1)
.setId(thePath);
DaoMethodOutcome outcome = myStructureDefinitionDao.update(sd, new SystemRequestDetails());
assertNotNull(outcome.getResource());
}
}

View File

@ -0,0 +1,96 @@
package ca.uhn.fhir.jpa.validation;
import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome;
import ca.uhn.fhir.jpa.provider.BaseResourceProviderR4Test;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.SystemRequestDetails;
import ca.uhn.fhir.rest.gclient.TokenClientParam;
import ca.uhn.fhir.rest.param.UriParam;
import ca.uhn.fhir.rest.param.UriParamQualifierEnum;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.StructureDefinition;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class SearchWithResourceProfileR4Test extends BaseResourceProviderR4Test {
private static final String myResourceType = "Patient";
private final String myProfile = "http://example.org/fhir/StructureDefinition/TestPatient";
@Test
public void testSearchPatient_withProfileBelowCriteria_returnsAllMatches() {
createProfile();
IIdType id1 = createPatient(withProfile(myProfile));
IIdType id2 = createPatient(withProfile(myProfile + "|1"));
SearchParameterMap params = new SearchParameterMap();
params.add("_profile", new UriParam(myProfile).setQualifier(UriParamQualifierEnum.BELOW));
IBundleProvider bundleProvider = myPatientDao.search(params, mySrd);
assertFalse(bundleProvider.isEmpty());
assertThat(toUnqualifiedVersionlessIdValues(bundleProvider),
containsInAnyOrder(id1.toUnqualifiedVersionless().getValue(), id2.toUnqualifiedVersionless().getValue()));
}
@Test
public void testSearchPatient_withProfileExactCriteriaWithoutVersionAndPatientProfileWithoutVersion_returnsExactMatch() {
createProfile();
IIdType id1 = createPatient(withProfile(myProfile));
IIdType id2 = createPatient(withProfile(myProfile));
Bundle outcome = myClient.search().forResource(myResourceType)
.where(new TokenClientParam("_profile").exactly().code(myProfile))
.returnBundle(Bundle.class).execute();
assertThat(toUnqualifiedVersionlessIdValues(outcome),
containsInAnyOrder(id1.toUnqualifiedVersionless().getValue(), id2.toUnqualifiedVersionless().getValue()));
}
@Test
public void testSearchPatient_withProfileExactCriteriaWithVersionAndPatientProfileWithVersion_returnsExactMatch() {
createProfile();
IIdType id1 = createPatient(withProfile(myProfile + "|1"));
Bundle outcome = myClient.search().forResource(myResourceType)
.where(new TokenClientParam("_profile").exactly().code(myProfile + "|1"))
.returnBundle(Bundle.class).execute();
assertThat(toUnqualifiedVersionlessIdValues(outcome),
containsInAnyOrder(id1.toUnqualifiedVersionless().getValue()));
}
@Test
public void testSearchPatient_withProfileExactCriteria_returnsNoMatch() {
createProfile();
createPatient(withProfile(myProfile + "|1"));
Bundle outcome = myClient.search().forResource(myResourceType)
.where(new TokenClientParam("_profile").exactly().code(myProfile))
.returnBundle(Bundle.class).execute();
assertTrue(outcome.getEntryFirstRep().isEmpty());
}
private void createProfile() {
final String baseProfile = "http://hl7.org/fhir/StructureDefinition/Patient";
final String profileId = "TestProfile";
final String version = "1";
final String rulePath = "Patient.identifier";
StructureDefinition sd = new StructureDefinition()
.setUrl(myProfile).setVersion(version)
.setBaseDefinition(baseProfile)
.setType(myResourceType)
.setDerivation(StructureDefinition.TypeDerivationRule.CONSTRAINT);
sd.setId(profileId);
sd.getDifferential().addElement()
.setPath(rulePath)
.setMin(1)
.setId(rulePath);
DaoMethodOutcome outcome = myStructureDefinitionDao.update(sd, new SystemRequestDetails());
assertNotNull(outcome.getResource());
}
}

View File

@ -79,25 +79,11 @@
<dependency> <dependency>
<groupId>org.simplejavamail</groupId> <groupId>org.simplejavamail</groupId>
<artifactId>simple-java-mail</artifactId> <artifactId>simple-java-mail</artifactId>
<!-- Excluded in favor of jakarta.activation:jakarta.activation-api -->
<exclusions>
<exclusion>
<groupId>com.sun.activation</groupId>
<artifactId>jakarta.activation</artifactId>
</exclusion>
</exclusions>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.icegreen</groupId> <groupId>com.icegreen</groupId>
<artifactId>greenmail</artifactId> <artifactId>greenmail</artifactId>
<scope>compile</scope> <scope>compile</scope>
<!-- Excluded in favor of jakarta.activation:jakarta.activation-api -->
<exclusions>
<exclusion>
<groupId>com.sun.activation</groupId>
<artifactId>jakarta.activation</artifactId>
</exclusion>
</exclusions>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@ -21,9 +21,9 @@ package ca.uhn.fhir.rest.server.mail;
import jakarta.annotation.Nonnull; import jakarta.annotation.Nonnull;
import org.simplejavamail.api.email.Email; import org.simplejavamail.api.email.Email;
import org.simplejavamail.api.mailer.AsyncResponse;
import java.util.List; import java.util.List;
import java.util.function.Consumer;
public interface IMailSvc { public interface IMailSvc {
void sendMail(@Nonnull List<Email> theEmails); void sendMail(@Nonnull List<Email> theEmails);
@ -31,7 +31,5 @@ public interface IMailSvc {
void sendMail(@Nonnull Email theEmail); void sendMail(@Nonnull Email theEmail);
void sendMail( void sendMail(
@Nonnull Email theEmail, @Nonnull Email theEmail, @Nonnull Runnable theOnSuccess, @Nonnull Consumer<Throwable> theErrorHandler);
@Nonnull Runnable theOnSuccess,
@Nonnull AsyncResponse.ExceptionConsumer theErrorHandler);
} }

View File

@ -20,12 +20,9 @@
package ca.uhn.fhir.rest.server.mail; package ca.uhn.fhir.rest.server.mail;
import jakarta.annotation.Nonnull; import jakarta.annotation.Nonnull;
import org.apache.commons.lang3.Validate;
import org.simplejavamail.MailException; import org.simplejavamail.MailException;
import org.simplejavamail.api.email.Email; import org.simplejavamail.api.email.Email;
import org.simplejavamail.api.email.Recipient; import org.simplejavamail.api.email.Recipient;
import org.simplejavamail.api.mailer.AsyncResponse;
import org.simplejavamail.api.mailer.AsyncResponse.ExceptionConsumer;
import org.simplejavamail.api.mailer.Mailer; import org.simplejavamail.api.mailer.Mailer;
import org.simplejavamail.api.mailer.config.TransportStrategy; import org.simplejavamail.api.mailer.config.TransportStrategy;
import org.simplejavamail.mailer.MailerBuilder; import org.simplejavamail.mailer.MailerBuilder;
@ -33,6 +30,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class MailSvc implements IMailSvc { public class MailSvc implements IMailSvc {
@ -42,14 +41,14 @@ public class MailSvc implements IMailSvc {
private final Mailer myMailer; private final Mailer myMailer;
public MailSvc(@Nonnull MailConfig theMailConfig) { public MailSvc(@Nonnull MailConfig theMailConfig) {
Validate.notNull(theMailConfig); Objects.requireNonNull(theMailConfig);
myMailConfig = theMailConfig; myMailConfig = theMailConfig;
myMailer = makeMailer(myMailConfig); myMailer = makeMailer(myMailConfig);
} }
@Override @Override
public void sendMail(@Nonnull List<Email> theEmails) { public void sendMail(@Nonnull List<Email> theEmails) {
Validate.notNull(theEmails); Objects.requireNonNull(theEmails);
theEmails.forEach(theEmail -> send(theEmail, new OnSuccess(theEmail), new ErrorHandler(theEmail))); theEmails.forEach(theEmail -> send(theEmail, new OnSuccess(theEmail), new ErrorHandler(theEmail)));
} }
@ -60,21 +59,23 @@ public class MailSvc implements IMailSvc {
@Override @Override
public void sendMail( public void sendMail(
@Nonnull Email theEmail, @Nonnull Runnable theOnSuccess, @Nonnull ExceptionConsumer theErrorHandler) { @Nonnull Email theEmail, @Nonnull Runnable theOnSuccess, @Nonnull Consumer<Throwable> theErrorHandler) {
send(theEmail, theOnSuccess, theErrorHandler); send(theEmail, theOnSuccess, theErrorHandler);
} }
private void send( private void send(
@Nonnull Email theEmail, @Nonnull Runnable theOnSuccess, @Nonnull ExceptionConsumer theErrorHandler) { @Nonnull Email theEmail, @Nonnull Runnable theOnSuccess, @Nonnull Consumer<Throwable> theErrorHandler) {
Validate.notNull(theEmail); Objects.requireNonNull(theEmail);
Validate.notNull(theOnSuccess); Objects.requireNonNull(theOnSuccess);
Validate.notNull(theErrorHandler); Objects.requireNonNull(theErrorHandler);
try { try {
final AsyncResponse asyncResponse = myMailer.sendMail(theEmail, true); myMailer.sendMail(theEmail, true).whenComplete((result, ex) -> {
if (asyncResponse != null) { if (ex != null) {
asyncResponse.onSuccess(theOnSuccess); theErrorHandler.accept(ex);
asyncResponse.onException(theErrorHandler); } else {
theOnSuccess.run();
} }
});
} catch (MailException e) { } catch (MailException e) {
theErrorHandler.accept(e); theErrorHandler.accept(e);
} }
@ -117,7 +118,7 @@ public class MailSvc implements IMailSvc {
} }
} }
private class ErrorHandler implements ExceptionConsumer { private class ErrorHandler implements Consumer<Throwable> {
private final Email myEmail; private final Email myEmail;
private ErrorHandler(@Nonnull Email theEmail) { private ErrorHandler(@Nonnull Email theEmail) {
@ -125,7 +126,7 @@ public class MailSvc implements IMailSvc {
} }
@Override @Override
public void accept(Exception t) { public void accept(Throwable t) {
ourLog.error("Email not sent" + makeMessage(myEmail), t); ourLog.error("Email not sent" + makeMessage(myEmail), t);
} }
} }

View File

@ -4,6 +4,7 @@ import com.icegreen.greenmail.junit5.GreenMailExtension;
import com.icegreen.greenmail.util.GreenMailUtil; import com.icegreen.greenmail.util.GreenMailUtil;
import com.icegreen.greenmail.util.ServerSetupTest; import com.icegreen.greenmail.util.ServerSetupTest;
import jakarta.annotation.Nonnull; import jakarta.annotation.Nonnull;
import jakarta.mail.internet.MimeMessage;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.api.extension.RegisterExtension;
@ -11,7 +12,6 @@ import org.simplejavamail.MailException;
import org.simplejavamail.api.email.Email; import org.simplejavamail.api.email.Email;
import org.simplejavamail.email.EmailBuilder; import org.simplejavamail.email.EmailBuilder;
import javax.mail.internet.MimeMessage;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@ -86,13 +86,14 @@ public class MailSvcIT {
@Test @Test
public void testSendMailWithInvalidToAddressExpectErrorHandler() { public void testSendMailWithInvalidToAddressExpectErrorHandler() {
// setup // setup
final Email email = withEmail("xyz"); String invalidEmailAdress = "xyz";
final Email email = withEmail(invalidEmailAdress);
// execute // execute
fixture.sendMail(email, fixture.sendMail(email,
() -> fail("Should not execute on Success"), () -> fail("Should not execute on Success"),
(e) -> { (e) -> {
assertTrue(e instanceof MailException); assertTrue(e instanceof MailException);
assertEquals("Invalid TO address: " + email, e.getMessage()); assertEquals("Invalid TO address: " + invalidEmailAdress, e.getMessage());
}); });
// validate // validate
assertTrue(ourGreenMail.waitForIncomingEmail(1000, 0)); assertTrue(ourGreenMail.waitForIncomingEmail(1000, 0));

34
pom.xml
View File

@ -869,6 +869,7 @@
<developer> <developer>
<id>delopst</id> <id>delopst</id>
<name>Primož Delopst</name> <name>Primož Delopst</name>
<organization>Better</organization>
</developer> </developer>
<developer> <developer>
<id>Zach Smith</id> <id>Zach Smith</id>
@ -1160,27 +1161,38 @@
<dependency> <dependency>
<groupId>org.simplejavamail</groupId> <groupId>org.simplejavamail</groupId>
<artifactId>simple-java-mail</artifactId> <artifactId>simple-java-mail</artifactId>
<version>6.6.1</version> <version>8.11.2</version>
<exclusions> <exclusions>
<exclusion> <exclusion>
<groupId>com.sun.activation</groupId> <groupId>com.github.bbottema</groupId>
<artifactId>jakarta.activation-api</artifactId> <artifactId>jetbrains-runtime-annotations</artifactId>
</exclusion> </exclusion>
<exclusion> <exclusion>
<groupId>com.sun.activation</groupId> <groupId>jakarta.mail</groupId>
<artifactId>jakarta.activation</artifactId> <artifactId>jakarta.mail-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>jakarta.mail</groupId>
<artifactId>jakarta.mail-api</artifactId>
<version>2.1.3</version>
</dependency>
<dependency>
<groupId>com.icegreen</groupId>
<artifactId>greenmail</artifactId>
<version>2.1.0-rc-1</version>
<exclusions>
<exclusion>
<groupId>jakarta.mail</groupId>
<artifactId>jakarta.mail-api</artifactId>
</exclusion> </exclusion>
</exclusions> </exclusions>
</dependency> </dependency>
<dependency>
<groupId>com.icegreen</groupId>
<artifactId>greenmail</artifactId>
<version>1.6.4</version>
</dependency>
<dependency> <dependency>
<groupId>com.icegreen</groupId> <groupId>com.icegreen</groupId>
<artifactId>greenmail-junit5</artifactId> <artifactId>greenmail-junit5</artifactId>
<version>1.6.4</version> <version>2.1.0-rc-1</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<!-- mail end --> <!-- mail end -->