Compare commits

...

6 Commits

Author SHA1 Message Date
Brian Lindsey a8a6a03c3e
Merge d99d6ea1d2 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
Brian Lindsey d99d6ea1d2 update us core ig link 2023-11-19 11:41:20 -07:00
Brian Lindsey 1abf43c28d update supported hibernate databases link 2023-11-19 11:37:50 -07:00
16 changed files with 696 additions and 700 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

@ -14,7 +14,7 @@ The HAPI JPA Server has the following components:
* **Hibernate:** The HAPI JPA Server uses the JPA library, implemented by Hibernate. No Hibernate specific features are used, so the library should also work with other providers (e.g. Eclipselink) but it is not tested regularly with them.
* **Database:** The RESTful server uses an embedded Derby database, but can be configured to talk to [any database supported by Hibernate](https://developer.jboss.org/wiki/SupportedDatabases2?_sscc=t).
* **Database:** The RESTful server uses an embedded Derby database, but can be configured to talk to [any database supported by Hibernate](https://github.com/hibernate/hibernate-orm/blob/main/dialects.adoc).
# Schema

View File

@ -8,6 +8,6 @@ This section contains details on several strategies for validating resources:
* **[Instance Validator](./instance_validator.html)** is validation of the raw or parsed resource against the official FHIR validation rules (ie. the official FHIR definitions, expressed as profile resources such as [StructureDefinition](http://hl7.org/fhir/structuredefinition.html) and [ValueSet](http://hl7.org/fhir/valueset.html).
The Instance Validator can also be used to validate resources against individual Implementation Guides which derive from the core specification (e.g. the [US Core](http://hl7.com/uscore) implementation guide).
The Instance Validator can also be used to validate resources against individual Implementation Guides which derive from the core specification (e.g. the [US Core](https://build.fhir.org/ig/HL7/US-Core/) implementation guide).
* **[Schema/Schematron Validation](./schema_validator.html)** is validation using XSD/SCH validation files provided by FHIR. This validator performs well but produces less usable error messages than Profile Validation. It is considered a legacy feature, as the Instance Validator is now mature and preferred.

View File

@ -800,14 +800,19 @@ public class ResourceLinkPredicateBuilder extends BaseJoiningPredicateBuilder im
subquery.addCustomColumns(1);
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(
BinaryCondition.equalTo(
getResourceIdColumn(),
theParams.getResourceTablePredicateBuilder().getResourceIdColumn()),
BinaryCondition.equalTo(
getResourceTypeColumn(),
generatePlaceholder(
theParams.getResourceTablePredicateBuilder().getResourceType())));
BinaryCondition.equalTo(getResourceTypeColumn(), generatePlaceholder(resourceType)),
ComboCondition.or(pathList.stream()
.map(path -> BinaryCondition.equalTo(getColumnSourcePath(), generatePlaceholder(path)))
.toArray(BinaryCondition[]::new)));
subquery.addCondition(subQueryCondition);

View File

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

View File

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

View File

@ -17,8 +17,8 @@ import org.junit.jupiter.api.extension.RegisterExtension;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import jakarta.mail.internet.InternetAddress;
import jakarta.mail.internet.MimeMessage;
import java.util.Arrays;
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.springframework.beans.factory.annotation.Autowired;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import jakarta.mail.internet.InternetAddress;
import jakarta.mail.internet.MimeMessage;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

View File

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

View File

@ -79,25 +79,11 @@
<dependency>
<groupId>org.simplejavamail</groupId>
<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>
<groupId>com.icegreen</groupId>
<artifactId>greenmail</artifactId>
<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>
</dependencies>

View File

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

View File

@ -20,12 +20,9 @@
package ca.uhn.fhir.rest.server.mail;
import jakarta.annotation.Nonnull;
import org.apache.commons.lang3.Validate;
import org.simplejavamail.MailException;
import org.simplejavamail.api.email.Email;
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.config.TransportStrategy;
import org.simplejavamail.mailer.MailerBuilder;
@ -33,6 +30,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.stream.Collectors;
public class MailSvc implements IMailSvc {
@ -42,14 +41,14 @@ public class MailSvc implements IMailSvc {
private final Mailer myMailer;
public MailSvc(@Nonnull MailConfig theMailConfig) {
Validate.notNull(theMailConfig);
Objects.requireNonNull(theMailConfig);
myMailConfig = theMailConfig;
myMailer = makeMailer(myMailConfig);
}
@Override
public void sendMail(@Nonnull List<Email> theEmails) {
Validate.notNull(theEmails);
Objects.requireNonNull(theEmails);
theEmails.forEach(theEmail -> send(theEmail, new OnSuccess(theEmail), new ErrorHandler(theEmail)));
}
@ -60,21 +59,23 @@ public class MailSvc implements IMailSvc {
@Override
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);
}
private void send(
@Nonnull Email theEmail, @Nonnull Runnable theOnSuccess, @Nonnull ExceptionConsumer theErrorHandler) {
Validate.notNull(theEmail);
Validate.notNull(theOnSuccess);
Validate.notNull(theErrorHandler);
@Nonnull Email theEmail, @Nonnull Runnable theOnSuccess, @Nonnull Consumer<Throwable> theErrorHandler) {
Objects.requireNonNull(theEmail);
Objects.requireNonNull(theOnSuccess);
Objects.requireNonNull(theErrorHandler);
try {
final AsyncResponse asyncResponse = myMailer.sendMail(theEmail, true);
if (asyncResponse != null) {
asyncResponse.onSuccess(theOnSuccess);
asyncResponse.onException(theErrorHandler);
}
myMailer.sendMail(theEmail, true).whenComplete((result, ex) -> {
if (ex != null) {
theErrorHandler.accept(ex);
} else {
theOnSuccess.run();
}
});
} catch (MailException 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 ErrorHandler(@Nonnull Email theEmail) {
@ -125,7 +126,7 @@ public class MailSvc implements IMailSvc {
}
@Override
public void accept(Exception t) {
public void accept(Throwable 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.ServerSetupTest;
import jakarta.annotation.Nonnull;
import jakarta.mail.internet.MimeMessage;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
@ -11,7 +12,6 @@ import org.simplejavamail.MailException;
import org.simplejavamail.api.email.Email;
import org.simplejavamail.email.EmailBuilder;
import javax.mail.internet.MimeMessage;
import java.util.Arrays;
import java.util.List;
@ -86,13 +86,14 @@ public class MailSvcIT {
@Test
public void testSendMailWithInvalidToAddressExpectErrorHandler() {
// setup
final Email email = withEmail("xyz");
String invalidEmailAdress = "xyz";
final Email email = withEmail(invalidEmailAdress);
// execute
fixture.sendMail(email,
() -> fail("Should not execute on Success"),
(e) -> {
assertTrue(e instanceof MailException);
assertEquals("Invalid TO address: " + email, e.getMessage());
assertEquals("Invalid TO address: " + invalidEmailAdress, e.getMessage());
});
// validate
assertTrue(ourGreenMail.waitForIncomingEmail(1000, 0));

34
pom.xml
View File

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