Compare commits
5 Commits
06ad987d70
...
877aa14c4e
Author | SHA1 | Date |
---|---|---|
TipzCM | 877aa14c4e | |
Thomas Papke | 3f6d1eb29b | |
Tadgh | 377e44b6ca | |
leif stawnyczy | 5b50545a50 | |
leif stawnyczy | dd9dcfd501 |
|
@ -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!"
|
|
@ -436,7 +436,7 @@ public class TermDeferredStorageSvcImpl implements ITermDeferredStorageSvc, IHas
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isJobsExecuting() {
|
public boolean isJobsExecuting() {
|
||||||
cleanseEndedJobs();
|
cleanseEndedJobs();
|
||||||
|
|
||||||
return !myJobExecutions.isEmpty();
|
return !myJobExecutions.isEmpty();
|
||||||
|
|
|
@ -78,6 +78,8 @@ public interface ITermDeferredStorageSvc {
|
||||||
|
|
||||||
void logQueueForUnitTest();
|
void logQueueForUnitTest();
|
||||||
|
|
||||||
|
boolean isJobsExecuting();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Only to be used from tests - Disallow test timeouts on deferred tasks
|
* Only to be used from tests - Disallow test timeouts on deferred tasks
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
package ca.uhn.fhir.jpa.term;
|
package ca.uhn.fhir.jpa.term;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.batch2.api.IJobCoordinator;
|
||||||
|
import ca.uhn.fhir.batch2.jobs.reindex.ReindexAppCtx;
|
||||||
|
import ca.uhn.fhir.batch2.jobs.reindex.ReindexJobParameters;
|
||||||
|
import ca.uhn.fhir.batch2.model.JobInstanceStartRequest;
|
||||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||||
import ca.uhn.fhir.context.RuntimeSearchParam;
|
import ca.uhn.fhir.context.RuntimeSearchParam;
|
||||||
import ca.uhn.fhir.context.support.ConceptValidationOptions;
|
import ca.uhn.fhir.context.support.ConceptValidationOptions;
|
||||||
|
@ -9,6 +13,7 @@ import ca.uhn.fhir.i18n.Msg;
|
||||||
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
|
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
|
||||||
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
|
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
|
||||||
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoValueSet;
|
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoValueSet;
|
||||||
|
import ca.uhn.fhir.jpa.batch.models.Batch2JobStartResponse;
|
||||||
import ca.uhn.fhir.jpa.entity.TermCodeSystem;
|
import ca.uhn.fhir.jpa.entity.TermCodeSystem;
|
||||||
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
|
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
|
||||||
import ca.uhn.fhir.jpa.entity.TermConcept;
|
import ca.uhn.fhir.jpa.entity.TermConcept;
|
||||||
|
@ -25,9 +30,13 @@ import ca.uhn.fhir.jpa.term.api.ITermReadSvc;
|
||||||
import ca.uhn.fhir.jpa.term.custom.CustomTerminologySet;
|
import ca.uhn.fhir.jpa.term.custom.CustomTerminologySet;
|
||||||
import ca.uhn.fhir.jpa.util.SqlQuery;
|
import ca.uhn.fhir.jpa.util.SqlQuery;
|
||||||
import ca.uhn.fhir.jpa.util.ValueSetTestUtil;
|
import ca.uhn.fhir.jpa.util.ValueSetTestUtil;
|
||||||
|
import ca.uhn.fhir.parser.IParser;
|
||||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||||
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
|
import ca.uhn.fhir.rest.api.server.SystemRequestDetails;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
|
import ca.uhn.fhir.util.BundleBuilder;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import jakarta.annotation.Nonnull;
|
import jakarta.annotation.Nonnull;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
@ -45,16 +54,22 @@ import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.transaction.TransactionStatus;
|
import org.springframework.transaction.TransactionStatus;
|
||||||
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
|
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
|
||||||
import org.springframework.transaction.support.TransactionTemplate;
|
import org.springframework.transaction.support.TransactionTemplate;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static ca.uhn.fhir.batch2.jobs.termcodesystem.TermCodeSystemJobConfig.TERM_CODE_SYSTEM_DELETE_JOB_NAME;
|
||||||
|
import static ca.uhn.fhir.batch2.jobs.termcodesystem.TermCodeSystemJobConfig.TERM_CODE_SYSTEM_VERSION_DELETE_JOB_NAME;
|
||||||
import static ca.uhn.fhir.util.HapiExtensions.EXT_VALUESET_EXPANSION_MESSAGE;
|
import static ca.uhn.fhir.util.HapiExtensions.EXT_VALUESET_EXPANSION_MESSAGE;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.awaitility.Awaitility.await;
|
import static org.awaitility.Awaitility.await;
|
||||||
|
@ -2081,7 +2096,662 @@ public class ValueSetExpansionR4Test extends BaseTermR4Test implements IValueSet
|
||||||
outcome = myValueSetDao.validateCode(vs.getUrlElement(), null, new StringType("A"), cs.getUrlElement(), null, null, null, mySrd);
|
outcome = myValueSetDao.validateCode(vs.getUrlElement(), null, new StringType("A"), cs.getUrlElement(), null, null, null, mySrd);
|
||||||
assertEquals(false, outcome.isOk());
|
assertEquals(false, outcome.isOk());
|
||||||
assertThat(outcome.getMessage()).contains("Code validation occurred using a ValueSet expansion that was pre-calculated");
|
assertThat(outcome.getMessage()).contains("Code validation occurred using a ValueSet expansion that was pre-calculated");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void expandValuesetAfterReindex() {
|
||||||
|
// setup
|
||||||
|
IParser parser = myFhirContext.newJsonParser();
|
||||||
|
CodeSystem cs;
|
||||||
|
ValueSet vs;
|
||||||
|
String csStr;
|
||||||
|
{
|
||||||
|
String vsStr = """
|
||||||
|
{
|
||||||
|
"resourceType": "ValueSet",
|
||||||
|
"id": "0447bffa-01fa-4405-828a-96192e74a5d8",
|
||||||
|
"meta": {
|
||||||
|
"versionId": "2",
|
||||||
|
"lastUpdated": "2024-04-09T15:06:24.025+00:00",
|
||||||
|
"source": "#f4491e490a6a2900"
|
||||||
|
},
|
||||||
|
"url": "https://health.gov.on.ca/idms/fhir/ValueSet/IDMS-Submission-Types",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"name": "IDMS-SUBMISSION-TYPES",
|
||||||
|
"title": "IDMS Submission Types",
|
||||||
|
"status": "active",
|
||||||
|
"experimental": false,
|
||||||
|
"date": "2023-09-28",
|
||||||
|
"publisher": "IDMS",
|
||||||
|
"description": "List of Submission Types",
|
||||||
|
"compose": {
|
||||||
|
"include": [
|
||||||
|
{
|
||||||
|
"system": "https://health.gov.on.ca/idms/fhir/CodeSystem/Internal-Submission-Types"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
vs = parser.parseResource(ValueSet.class, vsStr);
|
||||||
|
csStr = """
|
||||||
|
{
|
||||||
|
"resourceType": "CodeSystem",
|
||||||
|
"id": "d9acd5b8-9533-4fa1-bb70-b4380957a8c3",
|
||||||
|
"meta": {
|
||||||
|
"versionId": "14",
|
||||||
|
"lastUpdated": "2024-06-03T17:49:56.580+00:00",
|
||||||
|
"source": "#261a82258b0978a8"
|
||||||
|
},
|
||||||
|
"url": "https://health.gov.on.ca/idms/fhir/CodeSystem/Internal-Submission-Types",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"name": "IDMS-Internal-Submission-Types",
|
||||||
|
"status": "active",
|
||||||
|
"date": "2023-09-07",
|
||||||
|
"publisher": "IDMS",
|
||||||
|
"description": "This contains a lists of codes Submission Type Codes.",
|
||||||
|
"content": "complete",
|
||||||
|
"concept": [
|
||||||
|
{
|
||||||
|
"code": "SUB-BRAND-PRODUCT",
|
||||||
|
"display": "New Brand Product (Non-New Chemical Entity)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-CLASSIFICATION",
|
||||||
|
"display": "Classification Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-CLINICIAN-LED-SUBMISSIONS",
|
||||||
|
"display": "Clinician-Led Submissions"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-DELISTING",
|
||||||
|
"display": "Delisting"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-DIN-CHANGE",
|
||||||
|
"display": "Drug Identification Number (DIN) Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-DISTRIBUTOR",
|
||||||
|
"display": "Distributor Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-DRUG-PRODUCT-NAME",
|
||||||
|
"display": "Drug Product Name Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-FORMULATION",
|
||||||
|
"display": "Formulation Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-GENERIC-LINE",
|
||||||
|
"display": "Generic Line Extension"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-GENERIC-PRODUCT",
|
||||||
|
"display": "New Generic Product"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-LINE-EXTENSION",
|
||||||
|
"display": "Line Extension"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-NEW-INDICATION",
|
||||||
|
"display": "New Indication"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-NEW-NATURAL",
|
||||||
|
"display": "New Natural Health Product"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-NEW-OVER-COUNTER",
|
||||||
|
"display": "New Over the Counter (OTC) Product"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-NEW-CHEMICAL",
|
||||||
|
"display": "New Chemical Entity"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-NEW-NUTRITIONAL",
|
||||||
|
"display": "New Nutrition Product"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-NUTRITIONAL-LINE",
|
||||||
|
"display": "Line Extension"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-NEW-BIOSIMILAR",
|
||||||
|
"display": "New Biosimilar"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-BIOSIMILAR-LINE",
|
||||||
|
"display": "Line Extension"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-NEW-DIABETIC",
|
||||||
|
"display": "New Diabetic Testing Agent (DTA)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-NEW-GLUCOUSE",
|
||||||
|
"display": "New Flash Glucose Monitoring (FGM) Product"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-NON-FORMULARY-SINGLE",
|
||||||
|
"display": "Non-Formulary Single Source"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-NON-FORMULARY-MULTIPLE",
|
||||||
|
"display": "Non-Formulary Multiple Source "
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-ORG-NAME",
|
||||||
|
"display": "Organization Name Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-OTHER-TYPE-IN",
|
||||||
|
"display": "Other"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-OWNERSHIP",
|
||||||
|
"display": "Ownership Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-PRICE-CHANGE",
|
||||||
|
"display": "Price Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-PRODUCT-DISCONTINUE",
|
||||||
|
"display": "Product Discontinuation"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-PRODUCT-MONOGRAPH",
|
||||||
|
"display": "Product Monograph Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-PRODUCT-NAME",
|
||||||
|
"display": "Product Name Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-PRODUCT-CHANGE",
|
||||||
|
"display": "Product Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-SPECIAL-PROJECTS",
|
||||||
|
"display": "Special Projects"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-TEMPORARY-BENEFITS",
|
||||||
|
"display": "Temporary Benefits"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-VALVED",
|
||||||
|
"display": "New Valved Holding Chamber (VHC)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-REDESIGNATION-BENEFITS",
|
||||||
|
"display": "Re-Designation of Benefits"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-MANUFACTURER-INQUIRIES",
|
||||||
|
"display": "Manufacturer Inquiries"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-CHALLENGES",
|
||||||
|
"display": "Challenges"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-NEW-LINE",
|
||||||
|
"display": "Line Extension"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-MULTI-DIN-CHANGE",
|
||||||
|
"display": "Drug Identification Number (DIN) Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-MULTI-DRUG-PRODUCT-NAME",
|
||||||
|
"display": "Drug Product Name Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-MULTI-PRODUCT-MONOGRAPH",
|
||||||
|
"display": "Product Monograph Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-MULTI-FORMULATION",
|
||||||
|
"display": "Formulation Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-MULTI-OWNERSHIP",
|
||||||
|
"display": "Ownership Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-MULTI-DISTRIBUTOR",
|
||||||
|
"display": "Distributor Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-MULTI-ORG-NAME",
|
||||||
|
"display": "Organization Name Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-MULTI-PRODUCT-DISCONTINUE",
|
||||||
|
"display": "Product Discontinuation"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-MULTI-DELISTING",
|
||||||
|
"display": "Delisting"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-MULTI-PRICE-CHANGE",
|
||||||
|
"display": "Price Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-MULTI-OTHER-TYPE-IN",
|
||||||
|
"display": "Other"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-BIO-DIN-CHANGE",
|
||||||
|
"display": "Drug Identification Number (DIN) Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-BIO-DRUG-PRODUCT-NAME",
|
||||||
|
"display": "Drug Product Name Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-BIO-PRODUCT-MONOGRAPH",
|
||||||
|
"display": "Product Monograph Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-BIO-FORMULATION",
|
||||||
|
"display": "Formulation Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-BIO-OWNERSHIP",
|
||||||
|
"display": "Ownership Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-BIO-DISTRIBUTOR",
|
||||||
|
"display": "Distributor Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-BIO-ORG-NAME",
|
||||||
|
"display": "Organization Name Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-BIO-PRODUCT-DISCONTINUE",
|
||||||
|
"display": "Product Discontinuation"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-BIO-DELISTING",
|
||||||
|
"display": "Delisting"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-BIO-PRICE-CHANGE",
|
||||||
|
"display": "Price Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-BIO-OTHER-TYPE-IN",
|
||||||
|
"display": "Other"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-OTC-DIN-CHANGE",
|
||||||
|
"display": "Drug Identification Number (DIN) Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-OTC-DRUG-PRODUCT-NAME",
|
||||||
|
"display": "Drug Product Name Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-OTC-PRODUCT-MONOGRAPH",
|
||||||
|
"display": "Product Monograph Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-OTC-FORMULATION",
|
||||||
|
"display": "Formulation Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-OTC-OWNERSHIP",
|
||||||
|
"display": "Ownership Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-OTC-DISTRIBUTOR",
|
||||||
|
"display": "Distributor Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-OTC-ORG-NAME",
|
||||||
|
"display": "Organization Name Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-OTC-PRODUCT-DISCONTINUE",
|
||||||
|
"display": "Product Discontinuation"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-OTC-DELISTING",
|
||||||
|
"display": "Delisting"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-OTC-PRICE-CHANGE",
|
||||||
|
"display": "Price Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-OTC-OTHER-TYPE-IN",
|
||||||
|
"display": "Other"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-DIABETIC-PRODUCT-NAME",
|
||||||
|
"display": "Product Name Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-DIABETIC-PRODUCT-CHANGE",
|
||||||
|
"display": "Product Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-DIABETIC-OWNERSHIP",
|
||||||
|
"display": "Ownership Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-DIABETIC-DISTRIBUTOR",
|
||||||
|
"display": "Distributor Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-DIABETIC-ORG-NAME",
|
||||||
|
"display": "Organization Name Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-DIABETIC-PRODUCT-DISCONTINUE",
|
||||||
|
"display": "Product Discontinuation"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-DIABETIC-DELISTING",
|
||||||
|
"display": "Delisting"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-DIABETIC-PRICE-CHANGE",
|
||||||
|
"display": "Price Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-DIABETIC-OTHER-TYPE-IN",
|
||||||
|
"display": "Other"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-GLUCOSE-PRODUCT-NAME",
|
||||||
|
"display": "Product Name Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-GLUCOSE-PRODUCT-CHANGE",
|
||||||
|
"display": "Product Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-GLUCOSE-OWNERSHIP",
|
||||||
|
"display": "Ownership Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-GLUCOSE-DISTRIBUTOR",
|
||||||
|
"display": "Distributor Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-GLUCOSE-ORG-NAME",
|
||||||
|
"display": "Organization Name Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-GLUCOSE-PRODUCT-DISCONTINUE",
|
||||||
|
"display": "Product Discontinuation"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-GLUCOSE-DELISTING",
|
||||||
|
"display": "Delisting"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-GLUCOSE-PRICE-CHANGE",
|
||||||
|
"display": "Price Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-GLUCOSE-OTHER-TYPE-IN",
|
||||||
|
"display": "Other"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-VALVED-PRODUCT-NAME",
|
||||||
|
"display": "Product Name Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-VALVED-PRODUCT-CHANGE",
|
||||||
|
"display": "Product Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-VALVED-OWNERSHIP",
|
||||||
|
"display": "Ownership Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-VALVED-DISTRIBUTOR",
|
||||||
|
"display": "Distributor Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-VALVED-ORG-NAME",
|
||||||
|
"display": "Organization Name Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-VALVED-PRODUCT-DISCONTINUE",
|
||||||
|
"display": "Product Discontinuation"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-VALVED-DELISTING",
|
||||||
|
"display": "Delisting"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-VALVED-PRICE-CHANGE",
|
||||||
|
"display": "Price Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-VALVED-OTHER-TYPE-IN",
|
||||||
|
"display": "Other"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-NATURAL-PRODUCT-NAME",
|
||||||
|
"display": "Product Name Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-NATURAL-PRODUCT-CHANGE",
|
||||||
|
"display": "Product Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-NATURAL-OWNERSHIP",
|
||||||
|
"display": "Ownership Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-NATURAL-DISTRIBUTOR",
|
||||||
|
"display": "Distributor Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-NATURAL-ORG-NAME",
|
||||||
|
"display": "Organization Name Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-NATURAL-PRODUCT-DISCONTINUE",
|
||||||
|
"display": "Product Discontinuation"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-NATURAL-DELISTING",
|
||||||
|
"display": "Delisting"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-NATURAL-PRICE-CHANGE",
|
||||||
|
"display": "Price Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-NATURAL-OTHER-TYPE-IN",
|
||||||
|
"display": "Other"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-OTHER-PRODUCT-NAME",
|
||||||
|
"display": "Product Name Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-OTHER-PRODUCT-CHANGE",
|
||||||
|
"display": "Product Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-OTHER-OWNERSHIP",
|
||||||
|
"display": "Ownership Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-OTHER-DISTRIBUTOR",
|
||||||
|
"display": "Distributor Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-OTHER-ORG-NAME",
|
||||||
|
"display": "Organization Name Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-OTHER-PRODUCT-DISCONTINUE",
|
||||||
|
"display": "Product Discontinuation"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-OTHER-DELISTING",
|
||||||
|
"display": "Delisting"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-OTHER-PRICE-CHANGE",
|
||||||
|
"display": "Price Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-OTHER-OTHER-TYPE-IN",
|
||||||
|
"display": "Other"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-NUTRITIONAL-PRODUCT-NAME",
|
||||||
|
"display": "Product Name Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-NUTRITIONAL-FORMULATION",
|
||||||
|
"display": "Formulation Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-NUTRITIONAL-DRUG-REGULATION",
|
||||||
|
"display": "Change in Food and Drug Regulation Classification"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-ADVERTISING-POLICY",
|
||||||
|
"display": "Change in Advertising Policy"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-NUTRITIONAL-OWNERSHIP",
|
||||||
|
"display": "Ownership Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-NUTRITIONAL-DISTRIBUTOR",
|
||||||
|
"display": "Distributor Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-NUTRITIONAL-ORG-NAME",
|
||||||
|
"display": "Organization Name Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-NUTRITIONAL-PRODUCT-DISCONTINUE",
|
||||||
|
"display": "Product Discontinuation"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-NUTRITIONAL-DELISTING",
|
||||||
|
"display": "Delisting"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-NUTRITIONAL-PRICE-CHANGE",
|
||||||
|
"display": "Price Change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "SUB-NUTRITIONAL-OTHER-TYPE-IN",
|
||||||
|
"display": "Other"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
cs = parser.parseResource(CodeSystem.class, csStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
RequestDetails rq = new SystemRequestDetails();
|
||||||
|
int csToCreate = 1;
|
||||||
|
|
||||||
|
// create a bunch of code systems
|
||||||
|
myValueSetDao.update(vs, rq);
|
||||||
|
String csUrl = cs.getUrl();
|
||||||
|
BundleBuilder builder = new BundleBuilder(myFhirContext);
|
||||||
|
// while (cs.getConcept().size() > 90) {
|
||||||
|
// cs.getConcept().remove(1);
|
||||||
|
// }
|
||||||
|
for (int i = 0; i < csToCreate; i++) {
|
||||||
|
if (i > 0) {
|
||||||
|
cs = parser.parseResource(CodeSystem.class, csStr);
|
||||||
|
cs.setId("cs" + i);
|
||||||
|
cs.setUrl(csUrl + "-" + i);
|
||||||
|
}
|
||||||
|
builder.addTransactionUpdateEntry(cs);
|
||||||
|
// myCodeSystemDao.update(cs, rq);
|
||||||
|
}
|
||||||
|
builder.setType("transaction");
|
||||||
|
Bundle bundle = (Bundle) builder.getBundle();
|
||||||
|
mySystemDao.transaction(rq, bundle);
|
||||||
|
|
||||||
|
System.out.println("XXXX " + myDeferredStorageSvc.isStorageQueueEmpty());
|
||||||
|
myDeferredStorageSvc.logQueueForUnitTest();
|
||||||
|
|
||||||
|
|
||||||
|
AtomicInteger counter = new AtomicInteger();
|
||||||
|
await()
|
||||||
|
.atMost(10, TimeUnit.SECONDS)
|
||||||
|
.pollDelay(500, TimeUnit.MILLISECONDS)
|
||||||
|
.until(() -> {
|
||||||
|
boolean isQueueEmpty = myDeferredStorageSvc.isStorageQueueEmpty(false);
|
||||||
|
if (!isQueueEmpty) {
|
||||||
|
myDeferredStorageSvc.saveAllDeferred();
|
||||||
|
}
|
||||||
|
return isQueueEmpty;
|
||||||
|
});
|
||||||
|
if (myDeferredStorageSvc.isJobsExecuting()) {
|
||||||
|
System.out.println("running jobs");
|
||||||
|
myDeferredStorageSvc.saveAllDeferred();
|
||||||
|
myBatch2JobHelper.awaitJobCompletion(TERM_CODE_SYSTEM_VERSION_DELETE_JOB_NAME);
|
||||||
|
myBatch2JobHelper.awaitJobCompletion(TERM_CODE_SYSTEM_DELETE_JOB_NAME);
|
||||||
|
|
||||||
|
}
|
||||||
|
System.out.println("XXX " + myDeferredStorageSvc.isStorageQueueEmpty() + " " + counter.get());
|
||||||
|
myDeferredStorageSvc.logQueueForUnitTest();
|
||||||
|
myDeferredStorageSvc.toString();
|
||||||
|
|
||||||
|
// myDeferredStorageSvc.saveAllDeferred();
|
||||||
|
|
||||||
|
// perform the reindex
|
||||||
|
ReindexJobParameters params = new ReindexJobParameters();
|
||||||
|
params.addUrl("CodeSystem?");
|
||||||
|
JobInstanceStartRequest startRequest = new JobInstanceStartRequest();
|
||||||
|
startRequest.setJobDefinitionId(ReindexAppCtx.JOB_REINDEX);
|
||||||
|
startRequest.setParameters(params);
|
||||||
|
System.out.println("xxxx starting reindex");
|
||||||
|
Batch2JobStartResponse response = myJobCoordinator.startInstance(rq, startRequest);
|
||||||
|
myBatch2JobHelper.awaitJobCompletion(response);
|
||||||
|
System.out.println("XXXX reindex done " + myDeferredStorageSvc.isStorageQueueEmpty());
|
||||||
|
|
||||||
|
// get the codes
|
||||||
|
SearchParameterMap spMap = new SearchParameterMap();
|
||||||
|
spMap.setLoadSynchronous(true);
|
||||||
|
IBundleProvider bp = myCodeSystemDao.search(spMap, rq);
|
||||||
|
|
||||||
|
// do value expansion
|
||||||
|
ValueSetExpansionOptions options = new ValueSetExpansionOptions();
|
||||||
|
options.setCount(200);
|
||||||
|
ValueSet expanded = myValueSetDao.expand(vs, options);
|
||||||
|
assertNotNull(expanded);
|
||||||
|
HashSet<String> all = new HashSet<>();
|
||||||
|
for (CodeSystem.ConceptDefinitionComponent set : cs.getConcept()) {
|
||||||
|
all.add(set.getCode());
|
||||||
|
}
|
||||||
|
for (ValueSet.ValueSetExpansionContainsComponent v : expanded.getExpansion().getContains()) {
|
||||||
|
all.remove(v.getCode());
|
||||||
|
}
|
||||||
|
assertTrue(all.isEmpty(), String.join(", ", all));
|
||||||
|
assertEquals(cs.getConcept().size(), expanded.getExpansion().getTotal());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IJobCoordinator myJobCoordinator;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ITermDeferredStorageSvc myDeferredStorageSvc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -59,7 +59,9 @@ public class ReindexAppCtx {
|
||||||
"Load IDs of resources to reindex",
|
"Load IDs of resources to reindex",
|
||||||
ResourceIdListWorkChunkJson.class,
|
ResourceIdListWorkChunkJson.class,
|
||||||
reindexLoadIdsStep(theBatch2DaoSvc))
|
reindexLoadIdsStep(theBatch2DaoSvc))
|
||||||
.addLastStep("reindex", "Perform the resource reindex", reindexStep())
|
.addLastStep("reindex",
|
||||||
|
"Perform the resource reindex",
|
||||||
|
reindexStep())
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
34
pom.xml
34
pom.xml
|
@ -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 -->
|
||||||
|
|
Loading…
Reference in New Issue