Preparing for email TLS support
This commit is contained in:
@@ -26,168 +26,178 @@ import java.sql.Driver;
|
|||||||
@EnableTransactionManagement()
|
@EnableTransactionManagement()
|
||||||
public class FhirServerConfigCommon {
|
public class FhirServerConfigCommon {
|
||||||
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirServerConfigCommon.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirServerConfigCommon.class);
|
||||||
|
|
||||||
private Boolean enableIndexMissingFields = HapiProperties.getEnableIndexMissingFields();
|
private Boolean enableIndexMissingFields = HapiProperties.getEnableIndexMissingFields();
|
||||||
private Boolean autoCreatePlaceholderReferenceTargets = HapiProperties.getAutoCreatePlaceholderReferenceTargets();
|
private Boolean autoCreatePlaceholderReferenceTargets = HapiProperties.getAutoCreatePlaceholderReferenceTargets();
|
||||||
private Boolean enforceReferentialIntegrityOnWrite = HapiProperties.getEnforceReferentialIntegrityOnWrite();
|
private Boolean enforceReferentialIntegrityOnWrite = HapiProperties.getEnforceReferentialIntegrityOnWrite();
|
||||||
private Boolean enforceReferentialIntegrityOnDelete = HapiProperties.getEnforceReferentialIntegrityOnDelete();
|
private Boolean enforceReferentialIntegrityOnDelete = HapiProperties.getEnforceReferentialIntegrityOnDelete();
|
||||||
private Boolean allowContainsSearches = HapiProperties.getAllowContainsSearches();
|
private Boolean allowContainsSearches = HapiProperties.getAllowContainsSearches();
|
||||||
private Boolean allowMultipleDelete = HapiProperties.getAllowMultipleDelete();
|
private Boolean allowMultipleDelete = HapiProperties.getAllowMultipleDelete();
|
||||||
private Boolean allowExternalReferences = HapiProperties.getAllowExternalReferences();
|
private Boolean allowExternalReferences = HapiProperties.getAllowExternalReferences();
|
||||||
private Boolean expungeEnabled = HapiProperties.getExpungeEnabled();
|
private Boolean expungeEnabled = HapiProperties.getExpungeEnabled();
|
||||||
private Boolean allowPlaceholderReferences = HapiProperties.getAllowPlaceholderReferences();
|
private Boolean allowPlaceholderReferences = HapiProperties.getAllowPlaceholderReferences();
|
||||||
private Boolean subscriptionRestHookEnabled = HapiProperties.getSubscriptionRestHookEnabled();
|
private Boolean subscriptionRestHookEnabled = HapiProperties.getSubscriptionRestHookEnabled();
|
||||||
private Boolean subscriptionEmailEnabled = HapiProperties.getSubscriptionEmailEnabled();
|
private Boolean subscriptionEmailEnabled = HapiProperties.getSubscriptionEmailEnabled();
|
||||||
private Boolean allowOverrideDefaultSearchParams = HapiProperties.getAllowOverrideDefaultSearchParams();
|
private Boolean allowOverrideDefaultSearchParams = HapiProperties.getAllowOverrideDefaultSearchParams();
|
||||||
private String emailFrom = HapiProperties.getEmailFrom();
|
private String emailFrom = HapiProperties.getEmailFrom();
|
||||||
private Boolean emailEnabled = HapiProperties.getEmailEnabled();
|
private Boolean emailEnabled = HapiProperties.getEmailEnabled();
|
||||||
private String emailHost = HapiProperties.getEmailHost();
|
private String emailHost = HapiProperties.getEmailHost();
|
||||||
private Integer emailPort = HapiProperties.getEmailPort();
|
private Integer emailPort = HapiProperties.getEmailPort();
|
||||||
private String emailUsername = HapiProperties.getEmailUsername();
|
private String emailUsername = HapiProperties.getEmailUsername();
|
||||||
private String emailPassword = HapiProperties.getEmailPassword();
|
private String emailPassword = HapiProperties.getEmailPassword();
|
||||||
@Autowired
|
private Boolean emailAuth = HapiProperties.getEmailAuth();
|
||||||
private SubscriptionDeliveryHandlerFactory mySubscriptionDeliveryHandlerFactory;
|
private Boolean emailStartTlsEnable = HapiProperties.getEmailStartTlsEnable();
|
||||||
|
private Boolean emailStartTlsRequired = HapiProperties.getEmailStartTlsRequired();
|
||||||
|
private Boolean emailQuitWait = HapiProperties.getEmailQuitWait();
|
||||||
|
|
||||||
public FhirServerConfigCommon() {
|
@Autowired
|
||||||
ourLog.info("Server configured to " + (this.allowContainsSearches ? "allow" : "deny") + " contains searches");
|
private SubscriptionDeliveryHandlerFactory mySubscriptionDeliveryHandlerFactory;
|
||||||
ourLog.info("Server configured to " + (this.allowMultipleDelete ? "allow" : "deny") + " multiple deletes");
|
|
||||||
ourLog.info("Server configured to " + (this.allowExternalReferences ? "allow" : "deny") + " external references");
|
|
||||||
ourLog.info("Server configured to " + (this.expungeEnabled ? "enable" : "disable") + " expunges");
|
|
||||||
ourLog.info("Server configured to " + (this.allowPlaceholderReferences ? "allow" : "deny") + " placeholder references");
|
|
||||||
ourLog.info("Server configured to " + (this.allowOverrideDefaultSearchParams ? "allow" : "deny") + " overriding default search params");
|
|
||||||
|
|
||||||
if (this.emailEnabled) {
|
public FhirServerConfigCommon() {
|
||||||
ourLog.info("Server is configured to enable email with host '" + this.emailHost + "' and port " + this.emailPort.toString());
|
ourLog.info("Server configured to " + (this.allowContainsSearches ? "allow" : "deny") + " contains searches");
|
||||||
ourLog.info("Server will use '" + this.emailFrom + "' as the from email address");
|
ourLog.info("Server configured to " + (this.allowMultipleDelete ? "allow" : "deny") + " multiple deletes");
|
||||||
|
ourLog.info("Server configured to " + (this.allowExternalReferences ? "allow" : "deny") + " external references");
|
||||||
|
ourLog.info("Server configured to " + (this.expungeEnabled ? "enable" : "disable") + " expunges");
|
||||||
|
ourLog.info("Server configured to " + (this.allowPlaceholderReferences ? "allow" : "deny") + " placeholder references");
|
||||||
|
ourLog.info("Server configured to " + (this.allowOverrideDefaultSearchParams ? "allow" : "deny") + " overriding default search params");
|
||||||
|
|
||||||
if (this.emailUsername != null && this.emailUsername.length() > 0) {
|
if (this.emailEnabled) {
|
||||||
ourLog.info("Server is configured to use username '" + this.emailUsername + "' for email");
|
ourLog.info("Server is configured to enable email with host '" + this.emailHost + "' and port " + this.emailPort.toString());
|
||||||
}
|
ourLog.info("Server will use '" + this.emailFrom + "' as the from email address");
|
||||||
|
|
||||||
if (this.emailPassword != null && this.emailPassword.length() > 0) {
|
if (this.emailUsername != null && this.emailUsername.length() > 0) {
|
||||||
ourLog.info("Server is configured to use a password for email");
|
ourLog.info("Server is configured to use username '" + this.emailUsername + "' for email");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (this.subscriptionRestHookEnabled) {
|
if (this.emailPassword != null && this.emailPassword.length() > 0) {
|
||||||
ourLog.info("REST-hook subscriptions enabled");
|
ourLog.info("Server is configured to use a password for email");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.subscriptionEmailEnabled) {
|
|
||||||
ourLog.info("Email subscriptions enabled");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
if (this.subscriptionRestHookEnabled) {
|
||||||
* Configure FHIR properties around the the JPA server via this bean
|
ourLog.info("REST-hook subscriptions enabled");
|
||||||
*/
|
|
||||||
@Bean()
|
|
||||||
public DaoConfig daoConfig() {
|
|
||||||
DaoConfig retVal = new DaoConfig();
|
|
||||||
|
|
||||||
retVal.setIndexMissingFields(this.enableIndexMissingFields ? DaoConfig.IndexEnabledEnum.ENABLED : DaoConfig.IndexEnabledEnum.DISABLED);
|
|
||||||
retVal.setAutoCreatePlaceholderReferenceTargets(this.autoCreatePlaceholderReferenceTargets);
|
|
||||||
retVal.setEnforceReferentialIntegrityOnWrite(this.enforceReferentialIntegrityOnWrite);
|
|
||||||
retVal.setEnforceReferentialIntegrityOnDelete(this.enforceReferentialIntegrityOnDelete);
|
|
||||||
retVal.setAllowContainsSearches(this.allowContainsSearches);
|
|
||||||
retVal.setAllowMultipleDelete(this.allowMultipleDelete);
|
|
||||||
retVal.setAllowExternalReferences(this.allowExternalReferences);
|
|
||||||
retVal.setExpungeEnabled(this.expungeEnabled);
|
|
||||||
retVal.setAutoCreatePlaceholderReferenceTargets(this.allowPlaceholderReferences);
|
|
||||||
retVal.setEmailFromAddress(this.emailFrom);
|
|
||||||
|
|
||||||
Integer maxFetchSize = HapiProperties.getMaximumFetchSize();
|
|
||||||
retVal.setFetchSizeDefaultMaximum(maxFetchSize);
|
|
||||||
ourLog.info("Server configured to have a maximum fetch size of " + (maxFetchSize == Integer.MAX_VALUE ? "'unlimited'" : maxFetchSize));
|
|
||||||
|
|
||||||
Long reuseCachedSearchResultsMillis = HapiProperties.getReuseCachedSearchResultsMillis();
|
|
||||||
retVal.setReuseCachedSearchResultsForMillis(reuseCachedSearchResultsMillis);
|
|
||||||
ourLog.info("Server configured to cache search results for {} milliseconds", reuseCachedSearchResultsMillis);
|
|
||||||
|
|
||||||
Long retainCachedSearchesMinutes = HapiProperties.getExpireSearchResultsAfterMins();
|
|
||||||
retVal.setExpireSearchResultsAfterMillis(retainCachedSearchesMinutes * 60 * 1000);
|
|
||||||
|
|
||||||
// Subscriptions are enabled by channel type
|
|
||||||
if (HapiProperties.getSubscriptionRestHookEnabled()) {
|
|
||||||
ourLog.info("Enabling REST-hook subscriptions");
|
|
||||||
retVal.addSupportedSubscriptionType(Subscription.SubscriptionChannelType.RESTHOOK);
|
|
||||||
}
|
|
||||||
if (HapiProperties.getSubscriptionEmailEnabled()) {
|
|
||||||
ourLog.info("Enabling email subscriptions");
|
|
||||||
retVal.addSupportedSubscriptionType(Subscription.SubscriptionChannelType.EMAIL);
|
|
||||||
}
|
|
||||||
if (HapiProperties.getSubscriptionWebsocketEnabled()) {
|
|
||||||
ourLog.info("Enabling websocket subscriptions");
|
|
||||||
retVal.addSupportedSubscriptionType(Subscription.SubscriptionChannelType.WEBSOCKET);
|
|
||||||
}
|
|
||||||
|
|
||||||
retVal.setFilterParameterEnabled(HapiProperties.getFilterSearchEnabled());
|
|
||||||
|
|
||||||
return retVal;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
if (this.subscriptionEmailEnabled) {
|
||||||
public ModelConfig modelConfig() {
|
ourLog.info("Email subscriptions enabled");
|
||||||
ModelConfig modelConfig = new ModelConfig();
|
}
|
||||||
modelConfig.setAllowContainsSearches(this.allowContainsSearches);
|
}
|
||||||
modelConfig.setAllowExternalReferences(this.allowExternalReferences);
|
|
||||||
modelConfig.setDefaultSearchParamsCanBeOverridden(this.allowOverrideDefaultSearchParams);
|
|
||||||
modelConfig.setEmailFromAddress(this.emailFrom);
|
|
||||||
|
|
||||||
// You can enable these if you want to support Subscriptions from your server
|
/**
|
||||||
if (this.subscriptionRestHookEnabled) {
|
* Configure FHIR properties around the the JPA server via this bean
|
||||||
modelConfig.addSupportedSubscriptionType(Subscription.SubscriptionChannelType.RESTHOOK);
|
*/
|
||||||
}
|
@Bean()
|
||||||
|
public DaoConfig daoConfig() {
|
||||||
|
DaoConfig retVal = new DaoConfig();
|
||||||
|
|
||||||
if (this.subscriptionEmailEnabled) {
|
retVal.setIndexMissingFields(this.enableIndexMissingFields ? DaoConfig.IndexEnabledEnum.ENABLED : DaoConfig.IndexEnabledEnum.DISABLED);
|
||||||
modelConfig.addSupportedSubscriptionType(Subscription.SubscriptionChannelType.EMAIL);
|
retVal.setAutoCreatePlaceholderReferenceTargets(this.autoCreatePlaceholderReferenceTargets);
|
||||||
}
|
retVal.setEnforceReferentialIntegrityOnWrite(this.enforceReferentialIntegrityOnWrite);
|
||||||
|
retVal.setEnforceReferentialIntegrityOnDelete(this.enforceReferentialIntegrityOnDelete);
|
||||||
|
retVal.setAllowContainsSearches(this.allowContainsSearches);
|
||||||
|
retVal.setAllowMultipleDelete(this.allowMultipleDelete);
|
||||||
|
retVal.setAllowExternalReferences(this.allowExternalReferences);
|
||||||
|
retVal.setExpungeEnabled(this.expungeEnabled);
|
||||||
|
retVal.setAutoCreatePlaceholderReferenceTargets(this.allowPlaceholderReferences);
|
||||||
|
retVal.setEmailFromAddress(this.emailFrom);
|
||||||
|
|
||||||
return modelConfig;
|
Integer maxFetchSize = HapiProperties.getMaximumFetchSize();
|
||||||
|
retVal.setFetchSizeDefaultMaximum(maxFetchSize);
|
||||||
|
ourLog.info("Server configured to have a maximum fetch size of " + (maxFetchSize == Integer.MAX_VALUE ? "'unlimited'" : maxFetchSize));
|
||||||
|
|
||||||
|
Long reuseCachedSearchResultsMillis = HapiProperties.getReuseCachedSearchResultsMillis();
|
||||||
|
retVal.setReuseCachedSearchResultsForMillis(reuseCachedSearchResultsMillis);
|
||||||
|
ourLog.info("Server configured to cache search results for {} milliseconds", reuseCachedSearchResultsMillis);
|
||||||
|
|
||||||
|
Long retainCachedSearchesMinutes = HapiProperties.getExpireSearchResultsAfterMins();
|
||||||
|
retVal.setExpireSearchResultsAfterMillis(retainCachedSearchesMinutes * 60 * 1000);
|
||||||
|
|
||||||
|
// Subscriptions are enabled by channel type
|
||||||
|
if (HapiProperties.getSubscriptionRestHookEnabled()) {
|
||||||
|
ourLog.info("Enabling REST-hook subscriptions");
|
||||||
|
retVal.addSupportedSubscriptionType(Subscription.SubscriptionChannelType.RESTHOOK);
|
||||||
|
}
|
||||||
|
if (HapiProperties.getSubscriptionEmailEnabled()) {
|
||||||
|
ourLog.info("Enabling email subscriptions");
|
||||||
|
retVal.addSupportedSubscriptionType(Subscription.SubscriptionChannelType.EMAIL);
|
||||||
|
}
|
||||||
|
if (HapiProperties.getSubscriptionWebsocketEnabled()) {
|
||||||
|
ourLog.info("Enabling websocket subscriptions");
|
||||||
|
retVal.addSupportedSubscriptionType(Subscription.SubscriptionChannelType.WEBSOCKET);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
retVal.setFilterParameterEnabled(HapiProperties.getFilterSearchEnabled());
|
||||||
* The following bean configures the database connection. The 'url' property value of "jdbc:derby:directory:jpaserver_derby_files;create=true" indicates that the server should save resources in a
|
|
||||||
* directory called "jpaserver_derby_files".
|
return retVal;
|
||||||
* <p>
|
}
|
||||||
* A URL to a remote database could also be placed here, along with login credentials and other properties supported by BasicDataSource.
|
|
||||||
*/
|
@Bean
|
||||||
@Bean(destroyMethod = "close")
|
public ModelConfig modelConfig() {
|
||||||
public BasicDataSource dataSource() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
|
ModelConfig modelConfig = new ModelConfig();
|
||||||
BasicDataSource retVal = new BasicDataSource();
|
modelConfig.setAllowContainsSearches(this.allowContainsSearches);
|
||||||
Driver driver = (Driver) Class.forName(HapiProperties.getDataSourceDriver()).getConstructor().newInstance();
|
modelConfig.setAllowExternalReferences(this.allowExternalReferences);
|
||||||
retVal.setDriver(driver);
|
modelConfig.setDefaultSearchParamsCanBeOverridden(this.allowOverrideDefaultSearchParams);
|
||||||
retVal.setUrl(HapiProperties.getDataSourceUrl());
|
modelConfig.setEmailFromAddress(this.emailFrom);
|
||||||
retVal.setUsername(HapiProperties.getDataSourceUsername());
|
|
||||||
retVal.setPassword(HapiProperties.getDataSourcePassword());
|
// You can enable these if you want to support Subscriptions from your server
|
||||||
retVal.setMaxTotal(HapiProperties.getDataSourceMaxPoolSize());
|
if (this.subscriptionRestHookEnabled) {
|
||||||
return retVal;
|
modelConfig.addSupportedSubscriptionType(Subscription.SubscriptionChannelType.RESTHOOK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Lazy
|
if (this.subscriptionEmailEnabled) {
|
||||||
@Bean
|
modelConfig.addSupportedSubscriptionType(Subscription.SubscriptionChannelType.EMAIL);
|
||||||
public IBinaryStorageSvc binaryStorageSvc() {
|
|
||||||
return new DatabaseBlobBinaryStorageSvcImpl();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean()
|
return modelConfig;
|
||||||
public IEmailSender emailSender() {
|
}
|
||||||
if (this.emailEnabled) {
|
|
||||||
JavaMailEmailSender retVal = new JavaMailEmailSender();
|
|
||||||
|
|
||||||
retVal.setSmtpServerHostname(this.emailHost);
|
/**
|
||||||
retVal.setSmtpServerPort(this.emailPort);
|
* The following bean configures the database connection. The 'url' property value of "jdbc:derby:directory:jpaserver_derby_files;create=true" indicates that the server should save resources in a
|
||||||
retVal.setSmtpServerUsername(this.emailUsername);
|
* directory called "jpaserver_derby_files".
|
||||||
retVal.setSmtpServerPassword(this.emailPassword);
|
* <p>
|
||||||
|
* A URL to a remote database could also be placed here, along with login credentials and other properties supported by BasicDataSource.
|
||||||
|
*/
|
||||||
|
@Bean(destroyMethod = "close")
|
||||||
|
public BasicDataSource dataSource() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
|
||||||
|
BasicDataSource retVal = new BasicDataSource();
|
||||||
|
Driver driver = (Driver) Class.forName(HapiProperties.getDataSourceDriver()).getConstructor().newInstance();
|
||||||
|
retVal.setDriver(driver);
|
||||||
|
retVal.setUrl(HapiProperties.getDataSourceUrl());
|
||||||
|
retVal.setUsername(HapiProperties.getDataSourceUsername());
|
||||||
|
retVal.setPassword(HapiProperties.getDataSourcePassword());
|
||||||
|
retVal.setMaxTotal(HapiProperties.getDataSourceMaxPoolSize());
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
Validate.notNull(mySubscriptionDeliveryHandlerFactory, "No subscription delivery handler");
|
@Lazy
|
||||||
mySubscriptionDeliveryHandlerFactory.setEmailSender(retVal);
|
@Bean
|
||||||
|
public IBinaryStorageSvc binaryStorageSvc() {
|
||||||
|
return new DatabaseBlobBinaryStorageSvcImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean()
|
||||||
|
public IEmailSender emailSender() {
|
||||||
|
if (this.emailEnabled) {
|
||||||
|
JavaMailEmailSender retVal = new JavaMailEmailSender();
|
||||||
|
|
||||||
|
retVal.setSmtpServerHostname(this.emailHost);
|
||||||
|
retVal.setSmtpServerPort(this.emailPort);
|
||||||
|
retVal.setSmtpServerUsername(this.emailUsername);
|
||||||
|
retVal.setSmtpServerPassword(this.emailPassword);
|
||||||
|
// TODO KHS add these when HAPI 4.2.0 is released
|
||||||
|
// retVal.setAuth(this.emailAuth);
|
||||||
|
// retVal.setStartTlsEnable(this.emailStartTlsEnable);
|
||||||
|
// retVal.setStartTlsRequired(this.emailStartTlsRequired);
|
||||||
|
// retVal.setQuitWait(this.emailQuitWait);
|
||||||
|
|
||||||
|
Validate.notNull(mySubscriptionDeliveryHandlerFactory, "No subscription delivery handler");
|
||||||
|
mySubscriptionDeliveryHandlerFactory.setEmailSender(retVal);
|
||||||
|
|
||||||
|
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -406,6 +406,12 @@ public class HapiProperties {
|
|||||||
return HapiProperties.getProperty("email.password");
|
return HapiProperties.getProperty("email.password");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Defaults from https://javaee.github.io/javamail/docs/api/com/sun/mail/smtp/package-summary.html
|
||||||
|
public static Boolean getEmailAuth() { return HapiProperties.getBooleanProperty("email.auth", false); }
|
||||||
|
public static Boolean getEmailStartTlsEnable() { return HapiProperties.getBooleanProperty("email.starttls.enable", false); }
|
||||||
|
public static Boolean getEmailStartTlsRequired() { return HapiProperties.getBooleanProperty("email.starttls.required", false); }
|
||||||
|
public static Boolean getEmailQuitWait() { return HapiProperties.getBooleanProperty("email.quitwait", true); }
|
||||||
|
|
||||||
public static Long getReuseCachedSearchResultsMillis() {
|
public static Long getReuseCachedSearchResultsMillis() {
|
||||||
String value = HapiProperties.getProperty(REUSE_CACHED_SEARCH_RESULTS_MILLIS, "60000");
|
String value = HapiProperties.getProperty(REUSE_CACHED_SEARCH_RESULTS_MILLIS, "60000");
|
||||||
return Long.valueOf(value);
|
return Long.valueOf(value);
|
||||||
|
|||||||
Reference in New Issue
Block a user