diff --git a/alerting/src/main/kotlin/com/amazon/opendistroforelasticsearch/alerting/AlertingPlugin.kt b/alerting/src/main/kotlin/com/amazon/opendistroforelasticsearch/alerting/AlertingPlugin.kt index da72c374..04e34b30 100644 --- a/alerting/src/main/kotlin/com/amazon/opendistroforelasticsearch/alerting/AlertingPlugin.kt +++ b/alerting/src/main/kotlin/com/amazon/opendistroforelasticsearch/alerting/AlertingPlugin.kt @@ -35,6 +35,7 @@ import com.amazon.opendistroforelasticsearch.alerting.resthandler.RestIndexMonit import com.amazon.opendistroforelasticsearch.alerting.resthandler.RestSearchMonitorAction import com.amazon.opendistroforelasticsearch.alerting.script.TriggerScript import com.amazon.opendistroforelasticsearch.alerting.settings.AlertingSettings +import com.amazon.opendistroforelasticsearch.alerting.settings.DestinationMailSettings import org.elasticsearch.action.ActionRequest import org.elasticsearch.action.ActionResponse import org.elasticsearch.client.Client @@ -167,12 +168,12 @@ internal class AlertingPlugin : PainlessExtension, ActionPlugin, ScriptPlugin, P AlertingSettings.ALERTING_MAX_MONITORS, AlertingSettings.REQUEST_TIMEOUT, AlertingSettings.MAX_ACTION_THROTTLE_VALUE, - AlertingSettings.DESTINATION_MAIL_HOST, - AlertingSettings.DESTINATION_MAIL_PORT, - AlertingSettings.DESTINATION_MAIL_METHOD, - AlertingSettings.DESTINATION_MAIL_FROM, - AlertingSettings.DESTINATION_MAIL_USERNAME, - AlertingSettings.DESTINATION_MAIL_PASSWORD + DestinationMailSettings.DESTINATION_MAIL_HOST, + DestinationMailSettings.DESTINATION_MAIL_PORT, + DestinationMailSettings.DESTINATION_MAIL_METHOD, + DestinationMailSettings.DESTINATION_MAIL_FROM, + DestinationMailSettings.DESTINATION_MAIL_USERNAME, + DestinationMailSettings.DESTINATION_MAIL_PASSWORD ) } diff --git a/alerting/src/main/kotlin/com/amazon/opendistroforelasticsearch/alerting/MonitorRunner.kt b/alerting/src/main/kotlin/com/amazon/opendistroforelasticsearch/alerting/MonitorRunner.kt index 69cbf8e2..e9208851 100644 --- a/alerting/src/main/kotlin/com/amazon/opendistroforelasticsearch/alerting/MonitorRunner.kt +++ b/alerting/src/main/kotlin/com/amazon/opendistroforelasticsearch/alerting/MonitorRunner.kt @@ -50,6 +50,7 @@ import com.amazon.opendistroforelasticsearch.alerting.settings.AlertingSettings. import com.amazon.opendistroforelasticsearch.alerting.settings.AlertingSettings.Companion.ALERT_BACKOFF_MILLIS import com.amazon.opendistroforelasticsearch.alerting.settings.AlertingSettings.Companion.MOVE_ALERTS_BACKOFF_COUNT import com.amazon.opendistroforelasticsearch.alerting.settings.AlertingSettings.Companion.MOVE_ALERTS_BACKOFF_MILLIS +import com.amazon.opendistroforelasticsearch.alerting.settings.DestinationSettings import com.amazon.opendistroforelasticsearch.alerting.util.IndexUtils import org.apache.logging.log4j.LogManager import kotlinx.coroutines.CoroutineScope @@ -95,7 +96,7 @@ import java.time.Instant import kotlin.coroutines.CoroutineContext class MonitorRunner( - private val settings: Settings, + settings: Settings, private val client: Client, private val threadPool: ThreadPool, private val scriptService: ScriptService, @@ -115,6 +116,8 @@ class MonitorRunner( @Volatile private var moveAlertsRetryPolicy = BackoffPolicy.exponentialBackoff(MOVE_ALERTS_BACKOFF_MILLIS.get(settings), MOVE_ALERTS_BACKOFF_COUNT.get(settings)) + @Volatile private var destinationSettings = DestinationSettings.parse(settings) + init { clusterService.clusterSettings.addSettingsUpdateConsumer(ALERT_BACKOFF_MILLIS, ALERT_BACKOFF_COUNT) { millis, count -> retryPolicy = BackoffPolicy.constantBackoff(millis, count) @@ -434,7 +437,7 @@ class MonitorRunner( withContext(Dispatchers.IO) { val destination = getDestinationInfo(action.destinationId) actionOutput[MESSAGE_ID] = destination.publish( - settings.getAsSettings("opendistro_alerting.destination"), + destinationSettings, actionOutput[SUBJECT], actionOutput[MESSAGE]!! ) diff --git a/alerting/src/main/kotlin/com/amazon/opendistroforelasticsearch/alerting/model/destination/Destination.kt b/alerting/src/main/kotlin/com/amazon/opendistroforelasticsearch/alerting/model/destination/Destination.kt index b81e40dd..2abe1e99 100644 --- a/alerting/src/main/kotlin/com/amazon/opendistroforelasticsearch/alerting/model/destination/Destination.kt +++ b/alerting/src/main/kotlin/com/amazon/opendistroforelasticsearch/alerting/model/destination/Destination.kt @@ -26,11 +26,10 @@ import com.amazon.opendistroforelasticsearch.alerting.destination.response.Desti import com.amazon.opendistroforelasticsearch.alerting.elasticapi.convertToMap import com.amazon.opendistroforelasticsearch.alerting.elasticapi.instant import com.amazon.opendistroforelasticsearch.alerting.elasticapi.optionalTimeField -import com.amazon.opendistroforelasticsearch.alerting.settings.AlertingSettings +import com.amazon.opendistroforelasticsearch.alerting.settings.DestinationSettings import com.amazon.opendistroforelasticsearch.alerting.util.DestinationType import com.amazon.opendistroforelasticsearch.alerting.util.IndexUtils.Companion.NO_SCHEMA_VERSION import org.apache.logging.log4j.LogManager -import org.elasticsearch.common.settings.Settings import org.elasticsearch.common.xcontent.ToXContent import org.elasticsearch.common.xcontent.XContentBuilder import org.elasticsearch.common.xcontent.XContentParser @@ -154,7 +153,7 @@ data class Destination( } @Throws(IOException::class) - fun publish(settings: Settings?, compiledSubject: String?, compiledMessage: String): String { + fun publish(DestinationSettings: DestinationSettings, compiledSubject: String?, compiledMessage: String): String { val destinationMessage: BaseMessage val responseContent: String val responseStatusCode: Int @@ -186,14 +185,14 @@ data class Destination( } DestinationType.MAIL -> { destinationMessage = MailMessage.Builder(name) - .withHost(AlertingSettings.DESTINATION_MAIL_HOST.get(settings)) - .withPort(AlertingSettings.DESTINATION_MAIL_PORT.get(settings)) - .withMethod(AlertingSettings.DESTINATION_MAIL_METHOD.get(settings)) - .withFrom(AlertingSettings.DESTINATION_MAIL_FROM.get(settings)) + .withHost(DestinationSettings.mail.host) + .withPort(DestinationSettings.mail.port) + .withMethod(DestinationSettings.mail.method) + .withFrom(DestinationSettings.mail.from) .withRecipients(mail?.recipients) .withSubject(compiledSubject) - .withUserName(AlertingSettings.DESTINATION_MAIL_USERNAME.get(settings)) - .withPassword(AlertingSettings.DESTINATION_MAIL_PASSWORD.get(settings)) + .withUserName(DestinationSettings.mail.username) + .withPassword(DestinationSettings.mail.password) .withMessage(compiledMessage).build() } DestinationType.TEST_ACTION -> { diff --git a/alerting/src/main/kotlin/com/amazon/opendistroforelasticsearch/alerting/settings/AlertingSettings.kt b/alerting/src/main/kotlin/com/amazon/opendistroforelasticsearch/alerting/settings/AlertingSettings.kt index 0feef290..418d0053 100644 --- a/alerting/src/main/kotlin/com/amazon/opendistroforelasticsearch/alerting/settings/AlertingSettings.kt +++ b/alerting/src/main/kotlin/com/amazon/opendistroforelasticsearch/alerting/settings/AlertingSettings.kt @@ -17,7 +17,6 @@ package com.amazon.opendistroforelasticsearch.alerting.settings import com.amazon.opendistroforelasticsearch.alerting.AlertingPlugin import org.elasticsearch.common.settings.Setting -import org.elasticsearch.common.settings.SecureSetting import org.elasticsearch.common.unit.TimeValue import java.util.concurrent.TimeUnit @@ -118,41 +117,6 @@ class AlertingSettings { val MAX_ACTION_THROTTLE_VALUE = Setting.positiveTimeSetting( "opendistro.alerting.action_throttle_max_value", TimeValue.timeValueHours(24), - Setting.Property.NodeScope, Setting.Property.Dynamic - ) - - val DESTINATION_MAIL_HOST = Setting.simpleString( - "opendistro.alerting.destination.mail.host", - "localhost", - Setting.Property.NodeScope, Setting.Property.Dynamic - ) - - val DESTINATION_MAIL_PORT = Setting.intSetting( - "opendistro.alerting.destination.mail.port", - 25, - Setting.Property.NodeScope, Setting.Property.Dynamic - ) - - val DESTINATION_MAIL_METHOD = Setting.simpleString( - "opendistro.alerting.destination.mail.method", - "none", - Setting.Property.NodeScope, Setting.Property.Dynamic - ) - - val DESTINATION_MAIL_FROM = Setting.simpleString( - "opendistro.alerting.destination.mail.from", - "opendistro-alerting@localhost", - Setting.Property.NodeScope, Setting.Property.Dynamic - ) - - val DESTINATION_MAIL_USERNAME = SecureSetting.secureString( - "opendistro.alerting.destination.mail.username", - null - ) - - val DESTINATION_MAIL_PASSWORD = SecureSetting.secureString( - "opendistro.alerting.destination.mail.password", - null - ) + Setting.Property.NodeScope, Setting.Property.Dynamic) } } diff --git a/alerting/src/main/kotlin/com/amazon/opendistroforelasticsearch/alerting/settings/DestinationMailSettings.kt b/alerting/src/main/kotlin/com/amazon/opendistroforelasticsearch/alerting/settings/DestinationMailSettings.kt new file mode 100644 index 00000000..a10cd143 --- /dev/null +++ b/alerting/src/main/kotlin/com/amazon/opendistroforelasticsearch/alerting/settings/DestinationMailSettings.kt @@ -0,0 +1,68 @@ +package com.amazon.opendistroforelasticsearch.alerting.settings + +import org.elasticsearch.common.settings.Setting +import org.elasticsearch.common.settings.Settings +import org.elasticsearch.common.settings.SecureSetting +import org.elasticsearch.common.settings.SecureString +import java.io.IOException + +/** + * settings specific to mail destination. + */ +data class DestinationMailSettings( + val host: String, + val port: Int, + val method: String, + val from: String, + val username: SecureString, + val password: SecureString +) { + companion object { + val DESTINATION_MAIL_HOST = Setting.simpleString( + "opendistro.alerting.destination.mail.host", + "localhost", + Setting.Property.NodeScope, Setting.Property.Dynamic + ) + + val DESTINATION_MAIL_PORT = Setting.intSetting( + "opendistro.alerting.destination.mail.port", + 25, + Setting.Property.NodeScope, Setting.Property.Dynamic + ) + + val DESTINATION_MAIL_METHOD = Setting.simpleString( + "opendistro.alerting.destination.mail.method", + "none", + Setting.Property.NodeScope, Setting.Property.Dynamic + ) + + val DESTINATION_MAIL_FROM = Setting.simpleString( + "opendistro.alerting.destination.mail.from", + "opendistro-alerting@localhost", + Setting.Property.NodeScope, Setting.Property.Dynamic + ) + + val DESTINATION_MAIL_USERNAME = SecureSetting.secureString( + "opendistro.alerting.destination.mail.username", + null + ) + + val DESTINATION_MAIL_PASSWORD = SecureSetting.secureString( + "opendistro.alerting.destination.mail.password", + null + ) + + @JvmStatic + @Throws(IOException::class) + fun parse(settings: Settings): DestinationMailSettings { + return DestinationMailSettings( + DESTINATION_MAIL_HOST.get(settings), + DESTINATION_MAIL_PORT.get(settings), + DESTINATION_MAIL_METHOD.get(settings), + DESTINATION_MAIL_FROM.get(settings), + DESTINATION_MAIL_USERNAME.get(settings), + DESTINATION_MAIL_PASSWORD.get(settings) + ) + } + } +} diff --git a/alerting/src/main/kotlin/com/amazon/opendistroforelasticsearch/alerting/settings/DestinationSettings.kt b/alerting/src/main/kotlin/com/amazon/opendistroforelasticsearch/alerting/settings/DestinationSettings.kt new file mode 100644 index 00000000..be69b698 --- /dev/null +++ b/alerting/src/main/kotlin/com/amazon/opendistroforelasticsearch/alerting/settings/DestinationSettings.kt @@ -0,0 +1,22 @@ +package com.amazon.opendistroforelasticsearch.alerting.settings + +import org.elasticsearch.common.settings.Settings +import java.io.IOException + +/** + * settings specific to mail destination. + */ +data class DestinationSettings( + val mail: DestinationMailSettings +) { + companion object { + @JvmStatic + @Throws(IOException::class) + fun parse(settings: Settings): DestinationSettings { + val prefix: (String) -> (Boolean) = { it.startsWith("opendistro.alerting.destination.mail") } + return DestinationSettings( + DestinationMailSettings.parse(settings.filter(prefix)) + ) + } + } +} diff --git a/notification/src/main/java/com/amazon/opendistroforelasticsearch/alerting/destination/client/DestinationMailClient.java b/notification/src/main/java/com/amazon/opendistroforelasticsearch/alerting/destination/client/DestinationMailClient.java index 7aaf01ee..d328333d 100644 --- a/notification/src/main/java/com/amazon/opendistroforelasticsearch/alerting/destination/client/DestinationMailClient.java +++ b/notification/src/main/java/com/amazon/opendistroforelasticsearch/alerting/destination/client/DestinationMailClient.java @@ -24,9 +24,7 @@ import java.util.Properties; import javax.mail.*; import javax.mail.internet.InternetAddress; -import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; -import javax.mail.internet.MimeMultipart; /** * This class handles the connections to the given Destination. diff --git a/notification/src/test/java/com/amazon/opendistroforelasticsearch/alerting/destination/MailDestinationTest.java b/notification/src/test/java/com/amazon/opendistroforelasticsearch/alerting/destination/MailDestinationTest.java index dfcdd4da..80e01223 100644 --- a/notification/src/test/java/com/amazon/opendistroforelasticsearch/alerting/destination/MailDestinationTest.java +++ b/notification/src/test/java/com/amazon/opendistroforelasticsearch/alerting/destination/MailDestinationTest.java @@ -101,7 +101,7 @@ public void testHostMissingMessage() { .withMessage("dummyMessage") .withFrom("test@abc.com") .withRecipients("test@abc.com").build(); - + } catch (Exception ex) { Assert.assertEquals("Host name should be provided", ex.getMessage()); throw ex; @@ -128,13 +128,13 @@ public void testFromMissingMessage() { .withMessage("dummyMessage") .withHost("abc.com") .withRecipients("test@abc.com").build(); - + } catch (Exception ex) { Assert.assertEquals("From address should be provided", ex.getMessage()); throw ex; } } - + @Test(expected = IllegalArgumentException.class) public void testRecipientsMissingMessage() { try { @@ -142,7 +142,7 @@ public void testRecipientsMissingMessage() { .withMessage("dummyMessage") .withHost("abc.com") .withFrom("test@abc.com").build(); - + } catch (Exception ex) { Assert.assertEquals("Comma separated recipients should be provided", ex.getMessage()); throw ex;