From 11f394dd24f66bb9efe6361eee04e12f604b4332 Mon Sep 17 00:00:00 2001 From: Mohammad Qureshi <47198598+qreshi@users.noreply.github.com> Date: Wed, 20 Apr 2022 13:09:21 -0700 Subject: [PATCH] Remove Alerting's notification subproject (#413) * Remove notification subproject Signed-off-by: Mohammad Qureshi <47198598+qreshi@users.noreply.github.com> * Remove publishing to maven in build script Signed-off-by: Mohammad Qureshi <47198598+qreshi@users.noreply.github.com> Signed-off-by: Angie Zhang --- alerting/build.gradle | 1 - .../opensearch/alerting/util/AlertingUtils.kt | 16 -- .../alerting/AlertingRestTestCase.kt | 7 +- .../alerting/util/AlertingUtilsTests.kt | 65 ------ notification/build.gradle | 85 ------- .../alerting/destination/Notification.java | 39 ---- .../client/DestinationEmailClient.java | 98 -------- .../client/DestinationEmailClientPool.java | 20 -- .../client/DestinationHttpClient.java | 172 -------------- .../client/DestinationHttpClientPool.java | 20 -- .../factory/ChimeDestinationFactory.java | 51 ----- .../CustomWebhookDestinationFactory.java | 52 ----- .../factory/DestinationFactory.java | 22 -- .../factory/DestinationFactoryProvider.java | 48 ---- .../factory/EmailDestinationFactory.java | 52 ----- .../factory/SlackDestinationFactory.java | 52 ----- .../destination/message/BaseMessage.java | 90 -------- .../destination/message/ChimeMessage.java | 70 ------ .../message/CustomWebhookMessage.java | 214 ------------------ .../destination/message/DestinationType.java | 13 -- .../destination/message/EmailMessage.java | 185 --------------- .../destination/message/SlackMessage.java | 80 ------- .../destination/response/BaseResponse.java | 24 -- .../response/DestinationResponse.java | 45 ---- .../destination/ChimeDestinationTest.java | 164 -------------- .../destination/CustomWebhookMessageTest.java | 206 ----------------- .../destination/EmailDestinationTest.java | 188 --------------- .../destination/SlackDestinationTest.java | 170 -------------- scripts/build.sh | 8 - settings.gradle | 2 - 30 files changed, 6 insertions(+), 2253 deletions(-) delete mode 100644 alerting/src/test/kotlin/org/opensearch/alerting/util/AlertingUtilsTests.kt delete mode 100644 notification/build.gradle delete mode 100644 notification/src/main/java/org/opensearch/alerting/destination/Notification.java delete mode 100644 notification/src/main/java/org/opensearch/alerting/destination/client/DestinationEmailClient.java delete mode 100644 notification/src/main/java/org/opensearch/alerting/destination/client/DestinationEmailClientPool.java delete mode 100644 notification/src/main/java/org/opensearch/alerting/destination/client/DestinationHttpClient.java delete mode 100644 notification/src/main/java/org/opensearch/alerting/destination/client/DestinationHttpClientPool.java delete mode 100644 notification/src/main/java/org/opensearch/alerting/destination/factory/ChimeDestinationFactory.java delete mode 100644 notification/src/main/java/org/opensearch/alerting/destination/factory/CustomWebhookDestinationFactory.java delete mode 100644 notification/src/main/java/org/opensearch/alerting/destination/factory/DestinationFactory.java delete mode 100644 notification/src/main/java/org/opensearch/alerting/destination/factory/DestinationFactoryProvider.java delete mode 100644 notification/src/main/java/org/opensearch/alerting/destination/factory/EmailDestinationFactory.java delete mode 100644 notification/src/main/java/org/opensearch/alerting/destination/factory/SlackDestinationFactory.java delete mode 100644 notification/src/main/java/org/opensearch/alerting/destination/message/BaseMessage.java delete mode 100644 notification/src/main/java/org/opensearch/alerting/destination/message/ChimeMessage.java delete mode 100644 notification/src/main/java/org/opensearch/alerting/destination/message/CustomWebhookMessage.java delete mode 100644 notification/src/main/java/org/opensearch/alerting/destination/message/DestinationType.java delete mode 100644 notification/src/main/java/org/opensearch/alerting/destination/message/EmailMessage.java delete mode 100644 notification/src/main/java/org/opensearch/alerting/destination/message/SlackMessage.java delete mode 100644 notification/src/main/java/org/opensearch/alerting/destination/response/BaseResponse.java delete mode 100644 notification/src/main/java/org/opensearch/alerting/destination/response/DestinationResponse.java delete mode 100644 notification/src/test/java/org/opensearch/alerting/destination/ChimeDestinationTest.java delete mode 100644 notification/src/test/java/org/opensearch/alerting/destination/CustomWebhookMessageTest.java delete mode 100644 notification/src/test/java/org/opensearch/alerting/destination/EmailDestinationTest.java delete mode 100644 notification/src/test/java/org/opensearch/alerting/destination/SlackDestinationTest.java diff --git a/alerting/build.gradle b/alerting/build.gradle index 89a19841a..ace860b40 100644 --- a/alerting/build.gradle +++ b/alerting/build.gradle @@ -64,7 +64,6 @@ dependencies { implementation "org.jetbrains:annotations:13.0" api project(":alerting-core") - api project(":alerting-notification") implementation "com.github.seancfoley:ipaddress:5.3.3" testImplementation "org.jetbrains.kotlin:kotlin-test:${kotlin_version}" diff --git a/alerting/src/main/kotlin/org/opensearch/alerting/util/AlertingUtils.kt b/alerting/src/main/kotlin/org/opensearch/alerting/util/AlertingUtils.kt index 8772ce704..5cf351c1f 100644 --- a/alerting/src/main/kotlin/org/opensearch/alerting/util/AlertingUtils.kt +++ b/alerting/src/main/kotlin/org/opensearch/alerting/util/AlertingUtils.kt @@ -5,12 +5,10 @@ package org.opensearch.alerting.util -import inet.ipaddr.IPAddressString import org.opensearch.action.index.IndexRequest import org.opensearch.action.index.IndexResponse import org.opensearch.action.support.WriteRequest import org.opensearch.alerting.core.model.ScheduledJob -import org.opensearch.alerting.destination.message.BaseMessage import org.opensearch.alerting.model.AggregationResultBucket import org.opensearch.alerting.model.BucketLevelTriggerRunResult import org.opensearch.alerting.model.Monitor @@ -49,20 +47,6 @@ fun Destination.isAllowed(allowList: List): Boolean = allowList.contains fun Destination.isTestAction(): Boolean = this.type == DestinationType.TEST_ACTION -fun BaseMessage.isHostInDenylist(networks: List): Boolean { - if (this.url != null || this.uri.host != null) { - val ipStr = IPAddressString(this.uri.host) - for (network in networks) { - val netStr = IPAddressString(network) - if (netStr.contains(ipStr)) { - return true - } - } - } - - return false -} - fun Monitor.isBucketLevelMonitor(): Boolean = this.monitorType == Monitor.MonitorType.BUCKET_LEVEL_MONITOR fun Monitor.isDocLevelMonitor(): Boolean = this.monitorType == Monitor.MonitorType.DOC_LEVEL_MONITOR diff --git a/alerting/src/test/kotlin/org/opensearch/alerting/AlertingRestTestCase.kt b/alerting/src/test/kotlin/org/opensearch/alerting/AlertingRestTestCase.kt index 276431250..a5be09ae9 100644 --- a/alerting/src/test/kotlin/org/opensearch/alerting/AlertingRestTestCase.kt +++ b/alerting/src/test/kotlin/org/opensearch/alerting/AlertingRestTestCase.kt @@ -138,7 +138,12 @@ abstract class AlertingRestTestCase : ODFERestTestCase() { // Create Alerting config index if it doesn't exist to avoid mapping issues with legacy destination indexing createAlertingConfigIndex() - val response = indexDocWithAdminClient(ScheduledJob.SCHEDULED_JOBS_INDEX, UUIDs.base64UUID(), destination.toJsonStringWithType(), refresh) + val response = indexDocWithAdminClient( + ScheduledJob.SCHEDULED_JOBS_INDEX, + UUIDs.base64UUID(), + destination.toJsonStringWithType(), + refresh + ) val destinationJson = jsonXContent.createParser( NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, response.entity.content diff --git a/alerting/src/test/kotlin/org/opensearch/alerting/util/AlertingUtilsTests.kt b/alerting/src/test/kotlin/org/opensearch/alerting/util/AlertingUtilsTests.kt deleted file mode 100644 index 8688bcf0d..000000000 --- a/alerting/src/test/kotlin/org/opensearch/alerting/util/AlertingUtilsTests.kt +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.opensearch.alerting.util - -import org.opensearch.alerting.destination.message.BaseMessage -import org.opensearch.alerting.destination.message.CustomWebhookMessage -import org.opensearch.test.OpenSearchTestCase -import java.util.HashMap - -class AlertingUtilsTests : OpenSearchTestCase() { - - private val HOST_DENY_LIST = listOf( - "127.0.0.0/8", - "10.0.0.0/8", - "172.16.0.0/12", - "192.168.0.0/16", - "0.0.0.0/8", - "9.9.9.9" // ip - ) - - fun `test ips in denylist`() { - val ips = listOf( - "127.0.0.1", // 127.0.0.0/8 - "10.0.0.1", // 10.0.0.0/8 - "10.11.12.13", // 10.0.0.0/8 - "172.16.0.1", // "172.16.0.0/12" - "192.168.0.1", // 192.168.0.0/16" - "0.0.0.1", // 0.0.0.0/8 - "9.9.9.9" - ) - for (ip in ips) { - val bm = createMessageWithHost(ip) - assertEquals(true, bm.isHostInDenylist(HOST_DENY_LIST)) - } - } - - fun `test url in denylist`() { - val urls = listOf("https://www.amazon.com", "https://mytest.com", "https://mytest.com") - for (url in urls) { - val bm = createMessageWithURl(url) - assertEquals(false, bm.isHostInDenylist(HOST_DENY_LIST)) - } - } - - private fun createMessageWithHost(host: String): BaseMessage { - return CustomWebhookMessage.Builder("abc") - .withHost(host) - .withPath("incomingwebhooks/383c0e2b-d028-44f4-8d38-696754bc4574") - .withMessage("{\"Content\":\"Message test\"}") - .withMethod("POST") - .withQueryParams(HashMap()).build() - } - - private fun createMessageWithURl(url: String): BaseMessage { - return CustomWebhookMessage.Builder("abc") - .withUrl(url) - .withPath("incomingwebhooks/383c0e2b-d028-44f4-8d38-696754bc4574") - .withMessage("{\"Content\":\"Message test\"}") - .withMethod("POST") - .withQueryParams(HashMap()).build() - } -} diff --git a/notification/build.gradle b/notification/build.gradle deleted file mode 100644 index 9bb548871..000000000 --- a/notification/build.gradle +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - */ - -apply plugin: 'com.github.johnrengelman.shadow' -apply plugin: 'java' -apply plugin: 'jacoco' -apply plugin: 'maven-publish' -apply plugin: 'signing' - -dependencies { - compileOnly "org.opensearch:opensearch:${opensearch_version}" - implementation "org.apache.httpcomponents:httpcore:4.4.5" - implementation "org.apache.httpcomponents:httpclient:4.5.13" - implementation "com.sun.mail:javax.mail:1.6.2" - - testImplementation "org.opensearch.test:framework:${opensearch_version}" - testImplementation "org.easymock:easymock:4.0.1" -} - -shadowJar { - relocate 'org.apache.http', 'org.opensearch.notification.repackage.org.apache.http' - relocate 'org.apache.commons.logging', 'org.opensearch.notification.repackage.org.apache.commons.logging' - relocate 'org.apache.commons.codec', 'org.opensearch.notification.repackage.org.apache.commons.codec' - classifier = null -} - -task sourcesJar(type: Jar) { - classifier = 'sources' - from sourceSets.main.allJava -} - -task javadocJar(type: Jar) { - classifier = 'javadoc' - from javadoc.destinationDir -} - -publishing { - repositories { - maven { - name = 'staging' - url = "${rootProject.buildDir}/local-staging-repo" - } - } - publications { - shadow(MavenPublication) { - project.shadow.component(it) - groupId = 'org.opensearch' - artifactId = 'notification' - - artifact sourcesJar - artifact javadocJar - - pom { - name = "Open Distro for Elasticsearch Notification" - packaging = "jar" - url = "https://github.com/opendistro-for-elasticsearch/alerting" - description = "Open Distro for Elasticsearch Notification" - scm { - connection = "scm:git@github.com:opendistro-for-elasticsearch/alerting.git" - developerConnection = "scm:git@github.com:opendistro-for-elasticsearch/alerting.git" - url = "git@github.com:opendistro-for-elasticsearch/alerting.git" - } - licenses { - license { - name = "The Apache License, Version 2.0" - url = "http://www.apache.org/licenses/LICENSE-2.0.txt" - } - } - developers { - developer { - id = "amazonwebservices" - organization = "Amazon Web Services" - organizationUrl = "https://aws.amazon.com" - } - } - } - } - } - - // TODO - enabled debug logging for the time being, remove this eventually - gradle.startParameter.setShowStacktrace(ShowStacktrace.ALWAYS) - gradle.startParameter.setLogLevel(LogLevel.DEBUG) -} diff --git a/notification/src/main/java/org/opensearch/alerting/destination/Notification.java b/notification/src/main/java/org/opensearch/alerting/destination/Notification.java deleted file mode 100644 index df6c610ef..000000000 --- a/notification/src/main/java/org/opensearch/alerting/destination/Notification.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.opensearch.alerting.destination; - -import org.opensearch.alerting.destination.factory.DestinationFactory; -import org.opensearch.alerting.destination.factory.DestinationFactoryProvider; -import org.opensearch.alerting.destination.message.BaseMessage; -import org.opensearch.alerting.destination.response.BaseResponse; - -import java.io.IOException; -import java.security.AccessController; -import java.security.PrivilegedAction; -import org.opensearch.alerting.destination.response.BaseResponse; - -/** - * This is a client facing Notification class to publish the messages - * to the Notification channels like chime, slack, webhooks etc - */ -public class Notification { - private DestinationFactoryProvider factoryProvider; - - /** - * Publishes the notification message to the corresponding notification - * channel - * - * @param notificationMessage - * @return BaseResponse - */ - public static BaseResponse publish(BaseMessage notificationMessage) throws IOException { - return AccessController.doPrivileged((PrivilegedAction) () -> { - DestinationFactory destinationFactory = DestinationFactoryProvider.getFactory(notificationMessage.getChannelType()); - return destinationFactory.publish(notificationMessage); - }); - } -} - diff --git a/notification/src/main/java/org/opensearch/alerting/destination/client/DestinationEmailClient.java b/notification/src/main/java/org/opensearch/alerting/destination/client/DestinationEmailClient.java deleted file mode 100644 index bf1441b20..000000000 --- a/notification/src/main/java/org/opensearch/alerting/destination/client/DestinationEmailClient.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.opensearch.alerting.destination.client; - -import org.opensearch.alerting.destination.message.BaseMessage; -import org.opensearch.alerting.destination.message.EmailMessage; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.util.ArrayList; -import java.util.List; -import java.util.Properties; -import javax.mail.Authenticator; -import javax.mail.internet.InternetAddress; -import javax.mail.internet.MimeMessage; -import javax.mail.Message; -import javax.mail.MessagingException; -import javax.mail.PasswordAuthentication; -import javax.mail.Session; -import javax.mail.Transport; - -/** - * This class handles the connections to the given Destination. - */ -public class DestinationEmailClient { - - private static final Logger logger = LogManager.getLogger(DestinationEmailClient.class); - - public String execute(BaseMessage message) throws Exception { - if (message instanceof EmailMessage) { - EmailMessage emailMessage = (EmailMessage) message; - Session session = null; - - Properties prop = new Properties(); - prop.put("mail.transport.protocol", "smtp"); - prop.put("mail.smtp.host", emailMessage.getHost()); - prop.put("mail.smtp.port", emailMessage.getPort()); - - if (emailMessage.getUsername() != null && !emailMessage.getUsername().equals("".toCharArray())) { - prop.put("mail.smtp.auth", true); - try { - session = Session.getInstance(prop, new Authenticator() { - protected PasswordAuthentication getPasswordAuthentication() { - return new PasswordAuthentication( - emailMessage.getUsername().toString(), - emailMessage.getPassword().toString()); - } - }); - } catch (IllegalStateException e) { - return e.getMessage(); - } - } else { - session = Session.getInstance(prop); - } - - switch(emailMessage.getMethod()) { - case "ssl": - prop.put("mail.smtp.ssl.enable", true); - break; - case "starttls": - prop.put("mail.smtp.starttls.enable", true); - break; - } - - try { - Message mailmsg = new MimeMessage(session); - mailmsg.setFrom(new InternetAddress(emailMessage.getFrom())); - mailmsg.setRecipients(Message.RecipientType.TO, getRecipientsAsAddresses(emailMessage.getRecipients())); - mailmsg.setSubject(emailMessage.getSubject()); - mailmsg.setText(emailMessage.getMessageContent()); - - SendMessage(mailmsg); - } catch (MessagingException e) { - throw new MessagingException(e.getMessage()); - } - } - return "Sent"; - } - - /* - * This method is useful for mocking the client - */ - public void SendMessage(Message msg) throws Exception { - Transport.send(msg); - } - - private InternetAddress[] getRecipientsAsAddresses(List recipients) throws Exception { - ArrayList addresses = new ArrayList<>(); - for (String recipient : recipients) { - addresses.add(new InternetAddress(recipient)); - } - - return addresses.toArray(new InternetAddress[0]); - } -} diff --git a/notification/src/main/java/org/opensearch/alerting/destination/client/DestinationEmailClientPool.java b/notification/src/main/java/org/opensearch/alerting/destination/client/DestinationEmailClientPool.java deleted file mode 100644 index f1e570964..000000000 --- a/notification/src/main/java/org/opensearch/alerting/destination/client/DestinationEmailClientPool.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.opensearch.alerting.destination.client; - -/** - * This class provides Client to the relevant destinations - */ -public final class DestinationEmailClientPool { - - private static final DestinationEmailClient emailClient = new DestinationEmailClient(); - - private DestinationEmailClientPool() { } - - public static DestinationEmailClient getEmailClient() { - return emailClient; - } -} diff --git a/notification/src/main/java/org/opensearch/alerting/destination/client/DestinationHttpClient.java b/notification/src/main/java/org/opensearch/alerting/destination/client/DestinationHttpClient.java deleted file mode 100644 index 57904a134..000000000 --- a/notification/src/main/java/org/opensearch/alerting/destination/client/DestinationHttpClient.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.opensearch.alerting.destination.client; - -import org.opensearch.alerting.destination.message.BaseMessage; -import org.opensearch.alerting.destination.message.CustomWebhookMessage; -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpEntityEnclosingRequestBase; -import org.apache.http.client.methods.HttpPatch; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.client.methods.HttpPut; -import org.apache.http.client.methods.HttpRequestBase; -import org.apache.http.client.utils.URIBuilder; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.DefaultHttpRequestRetryHandler; -import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; -import org.apache.http.util.EntityUtils; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.opensearch.alerting.destination.message.BaseMessage; -import org.opensearch.alerting.destination.message.CustomWebhookMessage; -import org.opensearch.common.Strings; -import org.opensearch.common.unit.TimeValue; -import org.opensearch.rest.RestStatus; - -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - - -/** - * This class handles the connections to the given Destination. - */ -public class DestinationHttpClient { - - private static final Logger logger = LogManager.getLogger(DestinationHttpClient.class); - - private static final int MAX_CONNECTIONS = 60; - private static final int MAX_CONNECTIONS_PER_ROUTE = 20; - private static final int TIMEOUT_MILLISECONDS = (int) TimeValue.timeValueSeconds(5).millis(); - private static final int SOCKET_TIMEOUT_MILLISECONDS = (int)TimeValue.timeValueSeconds(50).millis(); - - /** - * all valid response status - */ - private static final Set VALID_RESPONSE_STATUS = Collections.unmodifiableSet(new HashSet<>( - Arrays.asList(RestStatus.OK.getStatus(), RestStatus.CREATED.getStatus(), RestStatus.ACCEPTED.getStatus(), - RestStatus.NON_AUTHORITATIVE_INFORMATION.getStatus(), RestStatus.NO_CONTENT.getStatus(), - RestStatus.RESET_CONTENT.getStatus(), RestStatus.PARTIAL_CONTENT.getStatus(), - RestStatus.MULTI_STATUS.getStatus()))); - - private static CloseableHttpClient HTTP_CLIENT = createHttpClient(); - - private static CloseableHttpClient createHttpClient() { - RequestConfig config = RequestConfig.custom() - .setConnectTimeout(TIMEOUT_MILLISECONDS) - .setConnectionRequestTimeout(TIMEOUT_MILLISECONDS) - .setSocketTimeout(SOCKET_TIMEOUT_MILLISECONDS) - .build(); - - PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(); - connectionManager.setMaxTotal(MAX_CONNECTIONS); - connectionManager.setDefaultMaxPerRoute(MAX_CONNECTIONS_PER_ROUTE); - - return HttpClientBuilder.create() - .setDefaultRequestConfig(config) - .setConnectionManager(connectionManager) - .setRetryHandler(new DefaultHttpRequestRetryHandler()) - .useSystemProperties() - .build(); - } - - public String execute(BaseMessage message) throws Exception { - CloseableHttpResponse response = null; - try { - response = getHttpResponse(message); - validateResponseStatus(response); - return getResponseString(response); - } finally { - if (response != null) { - EntityUtils.consumeQuietly(response.getEntity()); - } - } - } - - private CloseableHttpResponse getHttpResponse(BaseMessage message) throws Exception { - URI uri = null; - HttpRequestBase httpRequest; - if (message instanceof CustomWebhookMessage) { - CustomWebhookMessage customWebhookMessage = (CustomWebhookMessage) message; - uri = customWebhookMessage.getUri(); - httpRequest = constructHttpRequest(((CustomWebhookMessage) message).getMethod()); - // set headers - Map headerParams = customWebhookMessage.getHeaderParams(); - if(headerParams == null || headerParams.isEmpty()) { - // set default header - httpRequest.setHeader("Content-Type", "application/json"); - } else { - for (Map.Entry e : customWebhookMessage.getHeaderParams().entrySet()) - httpRequest.setHeader(e.getKey(), e.getValue()); - } - } else { - httpRequest = new HttpPost(); - uri = message.getUri(); - } - - httpRequest.setURI(uri); - if (httpRequest instanceof HttpEntityEnclosingRequestBase){ - StringEntity entity = new StringEntity(extractBody(message), StandardCharsets.UTF_8); - ((HttpEntityEnclosingRequestBase) httpRequest).setEntity(entity); - } - - return HTTP_CLIENT.execute(httpRequest); - } - - private HttpRequestBase constructHttpRequest(String method) { - switch (method){ - case "POST": - return new HttpPost(); - case "PUT": - return new HttpPut(); - case "PATCH": - return new HttpPatch(); - default: - throw new IllegalArgumentException("Invalid method supplied"); - } - } - - public String getResponseString(CloseableHttpResponse response) throws IOException { - HttpEntity entity = response.getEntity(); - if (entity == null) - return "{}"; - - String responseString = EntityUtils.toString(entity); - logger.debug("Http response: " + responseString); - - return responseString; - } - - private void validateResponseStatus(HttpResponse response) throws IOException { - int statusCode = response.getStatusLine().getStatusCode(); - - if (!(VALID_RESPONSE_STATUS.contains(statusCode))) { - throw new IOException("Failed: " + response); - } - } - - private String extractBody(BaseMessage message) { - return message.getMessageContent(); - } - - /* - * This method is useful for Mocking the client - */ - public void setHttpClient(CloseableHttpClient httpClient) { - HTTP_CLIENT = httpClient; - } -} diff --git a/notification/src/main/java/org/opensearch/alerting/destination/client/DestinationHttpClientPool.java b/notification/src/main/java/org/opensearch/alerting/destination/client/DestinationHttpClientPool.java deleted file mode 100644 index f20c9490b..000000000 --- a/notification/src/main/java/org/opensearch/alerting/destination/client/DestinationHttpClientPool.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.opensearch.alerting.destination.client; - -/** - * This class provides Client to the relevant destinations - */ -public final class DestinationHttpClientPool { - - private static final DestinationHttpClient httpClient = new DestinationHttpClient(); - - private DestinationHttpClientPool() { } - - public static DestinationHttpClient getHttpClient() { - return httpClient; - } -} diff --git a/notification/src/main/java/org/opensearch/alerting/destination/factory/ChimeDestinationFactory.java b/notification/src/main/java/org/opensearch/alerting/destination/factory/ChimeDestinationFactory.java deleted file mode 100644 index 34da12d1a..000000000 --- a/notification/src/main/java/org/opensearch/alerting/destination/factory/ChimeDestinationFactory.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.opensearch.alerting.destination.factory; - -import org.opensearch.alerting.destination.client.DestinationHttpClient; -import org.opensearch.alerting.destination.client.DestinationHttpClientPool; -import org.opensearch.alerting.destination.message.ChimeMessage; -import org.opensearch.alerting.destination.response.DestinationResponse; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.opensearch.rest.RestStatus; - -/** - * This class handles the client responsible for submitting the messages to Chime destination. - */ -public class ChimeDestinationFactory implements DestinationFactory{ - - private static final Logger logger = LogManager.getLogger(ChimeDestinationFactory.class); - - private DestinationHttpClient destinationHttpClient; - - public ChimeDestinationFactory() { - this.destinationHttpClient = DestinationHttpClientPool.getHttpClient(); - } - - @Override - public DestinationResponse publish(ChimeMessage message) { - try { - String response = getClient(message).execute(message); - return new DestinationResponse.Builder().withStatusCode(RestStatus.OK.getStatus()).withResponseContent(response).build(); - } catch (Exception ex) { - logger.error("Exception publishing Message: " + message.toString(), ex); - throw new IllegalStateException(ex); - } - } - - @Override - public DestinationHttpClient getClient(ChimeMessage message) { - return destinationHttpClient; - } - - /* - * This function can be used to mock the client for unit test - */ - public void setClient(DestinationHttpClient client) { - this.destinationHttpClient = client; - } -} diff --git a/notification/src/main/java/org/opensearch/alerting/destination/factory/CustomWebhookDestinationFactory.java b/notification/src/main/java/org/opensearch/alerting/destination/factory/CustomWebhookDestinationFactory.java deleted file mode 100644 index 64e110b30..000000000 --- a/notification/src/main/java/org/opensearch/alerting/destination/factory/CustomWebhookDestinationFactory.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.opensearch.alerting.destination.factory; - -import org.opensearch.alerting.destination.client.DestinationHttpClient; -import org.opensearch.alerting.destination.client.DestinationHttpClientPool; -import org.opensearch.alerting.destination.message.CustomWebhookMessage; -import org.opensearch.alerting.destination.response.DestinationResponse; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.opensearch.rest.RestStatus; - -/** - * This class handles the client responsible for submitting the messages to custom webhook destination. - */ -public class CustomWebhookDestinationFactory implements DestinationFactory{ - - private static final Logger logger = LogManager.getLogger(CustomWebhookDestinationFactory.class); - - private DestinationHttpClient destinationHttpClient; - - public CustomWebhookDestinationFactory() { - this.destinationHttpClient = DestinationHttpClientPool.getHttpClient(); - } - - @Override - public DestinationResponse publish(CustomWebhookMessage message) { - try { - String response = getClient(message).execute(message); - return new DestinationResponse.Builder().withStatusCode(RestStatus.OK.getStatus()).withResponseContent(response).build(); - } catch (Exception ex) { - logger.error("Exception publishing Message: " + message.toString(), ex); - throw new IllegalStateException(ex); - } - } - - @Override - public DestinationHttpClient getClient(CustomWebhookMessage message) { - return destinationHttpClient; - } - - /* - * This function can be used to mock the client for unit test - */ - public void setClient(DestinationHttpClient client) { - this.destinationHttpClient = client; - } - -} \ No newline at end of file diff --git a/notification/src/main/java/org/opensearch/alerting/destination/factory/DestinationFactory.java b/notification/src/main/java/org/opensearch/alerting/destination/factory/DestinationFactory.java deleted file mode 100644 index 7276f0a70..000000000 --- a/notification/src/main/java/org/opensearch/alerting/destination/factory/DestinationFactory.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.opensearch.alerting.destination.factory; - -import org.opensearch.alerting.destination.message.BaseMessage; -import org.opensearch.alerting.destination.message.DestinationType; -import org.opensearch.alerting.destination.response.BaseResponse; - -/** - * Interface which enables to plug in multiple notification Channel Factories. - * - * @param message object of type [{@link DestinationType}] - * @param client to publish above message - */ -public interface DestinationFactory { - BaseResponse publish(T message); - - Y getClient(T message); -} diff --git a/notification/src/main/java/org/opensearch/alerting/destination/factory/DestinationFactoryProvider.java b/notification/src/main/java/org/opensearch/alerting/destination/factory/DestinationFactoryProvider.java deleted file mode 100644 index 69efe5b1c..000000000 --- a/notification/src/main/java/org/opensearch/alerting/destination/factory/DestinationFactoryProvider.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.opensearch.alerting.destination.factory; - -import org.opensearch.alerting.destination.message.DestinationType; - -import java.util.HashMap; -import java.util.Map; - -/* - * This class helps in fetching the right Channel Factory based on the - * type of the channel. - * A channel could be Email, Webhook etc - */ -public class DestinationFactoryProvider { - - private static Map destinationFactoryMap = new HashMap<>(); - - static { - destinationFactoryMap.put(DestinationType.CHIME, new ChimeDestinationFactory()); - destinationFactoryMap.put(DestinationType.SLACK, new SlackDestinationFactory()); - destinationFactoryMap.put(DestinationType.CUSTOMWEBHOOK, new CustomWebhookDestinationFactory()); - destinationFactoryMap.put(DestinationType.EMAIL, new EmailDestinationFactory()); - } - - /** - * Fetches the right channel factory based on the type of the channel - * - * @param destinationType [{@link DestinationType}] - * @return DestinationFactory factory object for above destination type - */ - public static DestinationFactory getFactory(DestinationType destinationType) { - if (!destinationFactoryMap.containsKey(destinationType)) { - throw new IllegalArgumentException("Invalid channel type"); - } - return destinationFactoryMap.get(destinationType); - } - - /* - * This function is to mock hooks for the unit test - */ - public static void setFactory(DestinationType type, DestinationFactory factory) { - destinationFactoryMap.put(type, factory); - } -} diff --git a/notification/src/main/java/org/opensearch/alerting/destination/factory/EmailDestinationFactory.java b/notification/src/main/java/org/opensearch/alerting/destination/factory/EmailDestinationFactory.java deleted file mode 100644 index c6920195c..000000000 --- a/notification/src/main/java/org/opensearch/alerting/destination/factory/EmailDestinationFactory.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.opensearch.alerting.destination.factory; - -import org.opensearch.alerting.destination.client.DestinationEmailClient; -import org.opensearch.alerting.destination.client.DestinationEmailClientPool; -import org.opensearch.alerting.destination.message.EmailMessage; -import org.opensearch.alerting.destination.response.DestinationResponse; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -/** - * This class handles the client responsible for submitting the messages to the Email destination. - */ -public class EmailDestinationFactory implements DestinationFactory{ - - private DestinationEmailClient destinationEmailClient; - - private static final Logger logger = LogManager.getLogger(EmailDestinationFactory.class); - - public EmailDestinationFactory() { - this.destinationEmailClient = DestinationEmailClientPool.getEmailClient(); - } - - @Override - public DestinationResponse publish(EmailMessage message) { - try { - String response = getClient(message).execute(message); - int status = response.equals("Sent") ? 0 : 1; - return new DestinationResponse.Builder().withStatusCode(status).withResponseContent(response).build(); - } catch (Exception ex) { - logger.error("Exception publishing Message: " + message.toString(), ex); - throw new IllegalStateException(ex); - } - } - - @Override - public DestinationEmailClient getClient(EmailMessage message) { - return destinationEmailClient; - } - - /* - * This function can be used to mock the client for unit test - */ - public void setClient(DestinationEmailClient client) { - this.destinationEmailClient = client; - } - -} diff --git a/notification/src/main/java/org/opensearch/alerting/destination/factory/SlackDestinationFactory.java b/notification/src/main/java/org/opensearch/alerting/destination/factory/SlackDestinationFactory.java deleted file mode 100644 index 5ebad4cf5..000000000 --- a/notification/src/main/java/org/opensearch/alerting/destination/factory/SlackDestinationFactory.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.opensearch.alerting.destination.factory; - -import org.opensearch.alerting.destination.client.DestinationHttpClient; -import org.opensearch.alerting.destination.client.DestinationHttpClientPool; -import org.opensearch.alerting.destination.message.SlackMessage; -import org.opensearch.alerting.destination.response.DestinationResponse; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.opensearch.rest.RestStatus; - -/** - * This class handles the client responsible for submitting the messages to Slack destination. - */ -public class SlackDestinationFactory implements DestinationFactory{ - - private DestinationHttpClient destinationHttpClient; - - private static final Logger logger = LogManager.getLogger(SlackDestinationFactory.class); - - public SlackDestinationFactory() { - this.destinationHttpClient = DestinationHttpClientPool.getHttpClient(); - } - - @Override - public DestinationResponse publish(SlackMessage message) { - try { - String response = getClient(message).execute(message); - return new DestinationResponse.Builder().withStatusCode(RestStatus.OK.getStatus()).withResponseContent(response).build(); - } catch (Exception ex) { - logger.error("Exception publishing Message: " + message.toString(), ex); - throw new IllegalStateException(ex); - } - } - - @Override - public DestinationHttpClient getClient(SlackMessage message) { - return destinationHttpClient; - } - - /* - * This function can be used to mock the client for unit test - */ - public void setClient(DestinationHttpClient client) { - this.destinationHttpClient = client; - } - -} diff --git a/notification/src/main/java/org/opensearch/alerting/destination/message/BaseMessage.java b/notification/src/main/java/org/opensearch/alerting/destination/message/BaseMessage.java deleted file mode 100644 index 0b7a73e09..000000000 --- a/notification/src/main/java/org/opensearch/alerting/destination/message/BaseMessage.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.opensearch.alerting.destination.message; - -import org.apache.http.client.utils.URIBuilder; -import org.opensearch.common.Strings; - -import java.net.URI; -import java.net.URISyntaxException; -import java.util.Map; - -/** - * This class holds the generic parameters required for a - * message. - */ -public abstract class BaseMessage { - - protected DestinationType destinationType; - protected String destinationName; - protected String url; - private String content; - - BaseMessage(final DestinationType destinationType, final String destinationName, final String content) { - if (destinationType == null) { - throw new IllegalArgumentException("Channel type must be defined"); - } - if (!Strings.hasLength(destinationName)) { - throw new IllegalArgumentException("Channel name must be defined"); - } - this.destinationType = destinationType; - this.destinationName = destinationName; - this.content = content; - } - - BaseMessage(final DestinationType destinationType, final String destinationName, - final String content, final String url) { - this(destinationType, destinationName, content); - if (url == null) { - throw new IllegalArgumentException("url is invalid or empty"); - } - this.url = url; - } - - public void setUrl(String url) { - this.url = url; - } - public DestinationType getChannelType() { - return destinationType; - } - - public String getChannelName() { - return destinationName; - } - - public String getMessageContent() { - return content; - } - - public String getUrl() { - return url; - } - - public URI getUri() { - return buildUri(getUrl().trim(), null, null, -1, null, null); - } - - protected URI buildUri(String endpoint, String scheme, String host, - int port, String path, Map queryParams) { - try { - if(Strings.isNullOrEmpty(endpoint)) { - if (Strings.isNullOrEmpty(scheme)) { - scheme = "https"; - } - URIBuilder uriBuilder = new URIBuilder(); - if(queryParams != null) { - for (Map.Entry e : queryParams.entrySet()) - uriBuilder.addParameter(e.getKey(), e.getValue()); - } - return uriBuilder.setScheme(scheme).setHost(host).setPort(port).setPath(path).build(); - } - return new URIBuilder(endpoint).build(); - } catch (URISyntaxException exception) { - throw new IllegalStateException("Error creating URI"); - } - } - -} diff --git a/notification/src/main/java/org/opensearch/alerting/destination/message/ChimeMessage.java b/notification/src/main/java/org/opensearch/alerting/destination/message/ChimeMessage.java deleted file mode 100644 index ec2b05918..000000000 --- a/notification/src/main/java/org/opensearch/alerting/destination/message/ChimeMessage.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.opensearch.alerting.destination.message; - -import org.opensearch.common.Strings; - -/** - * This class holds the contents of an Chime message - */ -public class ChimeMessage extends BaseMessage { - private String message; - private ChimeMessage(final DestinationType destinationType, - final String destinationName, - final String url, - final String message) { - - super(destinationType, destinationName, message, url); - - if (DestinationType.CHIME != destinationType) { - throw new IllegalArgumentException("Channel Type does not match CHIME"); - } - - if (Strings.isNullOrEmpty(message)) { - throw new IllegalArgumentException("Message content is missing"); - } - - this.message = message; - } - - @Override - public String toString() { - return "DestinationType: " + destinationType + ", DestinationName:" + destinationName + - ", Url: " + url + ", Message: " + message; - } - - public static class Builder { - private String message; - private DestinationType destinationType; - private String destinationName; - private String url; - - public Builder(String destinationName) { - this.destinationName = destinationName; - this.destinationType = DestinationType.CHIME; - } - - public ChimeMessage.Builder withMessage(String message) { - this.message = message; - return this; - } - - public ChimeMessage.Builder withUrl(String url) { - this.url = url; - return this; - } - - public ChimeMessage build() { - ChimeMessage chimeMessage = new ChimeMessage(this.destinationType, this.destinationName, this.url, - this.message); - return chimeMessage; - } - } - - public String getUrl() { - return url; - } -} diff --git a/notification/src/main/java/org/opensearch/alerting/destination/message/CustomWebhookMessage.java b/notification/src/main/java/org/opensearch/alerting/destination/message/CustomWebhookMessage.java deleted file mode 100644 index f204e002e..000000000 --- a/notification/src/main/java/org/opensearch/alerting/destination/message/CustomWebhookMessage.java +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.opensearch.alerting.destination.message; - -import org.apache.http.client.methods.HttpPatch; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.client.methods.HttpPut; -import org.opensearch.common.Strings; - -import java.net.URI; -import java.util.Map; - -/** - * This class holds the content of an CustomWebhook message - */ -public class CustomWebhookMessage extends BaseMessage { - - private String message; - private String url; - private String scheme; - private String host; - private String method; - private int port; - private String path; - private Map queryParams; - private Map headerParams; - private final String userName; - private final String password; - - private CustomWebhookMessage(final DestinationType destinationType, - final String destinationName, - final String url, - final String scheme, - final String host, - final Integer port, - final String path, - final String method, - final Map queryParams, - final Map headerParams, - final String userName, - final String password, - final String message) { - - super(destinationType, destinationName, message); - - if (DestinationType.CUSTOMWEBHOOK != destinationType) { - throw new IllegalArgumentException("Channel Type does not match CustomWebhook"); - } - - if (!Strings.isNullOrEmpty(url)) { - setUrl(url.trim()); - } - - if (Strings.isNullOrEmpty(message)) { - throw new IllegalArgumentException("Message content is missing"); - } - - this.scheme = Strings.isNullOrEmpty(scheme) ? "https" : scheme; - this.port = port==null ? -1 : port; - - if (!Strings.isNullOrEmpty(path)) { - if (!path.startsWith("/")) { - this.path = "/" + path; - } - } - - if(Strings.isNullOrEmpty(url) && Strings.isNullOrEmpty(host)) { - throw new IllegalArgumentException("Either fully qualified URL or host name should be provided"); - } - - if (Strings.isNullOrEmpty(method)){ - // Default to POST for backwards compatibility - this.method = "POST"; - } else if (!HttpPost.METHOD_NAME.equals(method) && !HttpPut.METHOD_NAME.equals(method) - && !HttpPatch.METHOD_NAME.equals(method)) { - throw new IllegalArgumentException("Invalid method supplied. Only POST, PUT and PATCH are allowed"); - } else { - this.method = method; - } - - - this.message = message; - this.url = url; - this.host = host; - this.queryParams = queryParams; - this.headerParams = headerParams; - this.userName = userName; - this.password = password; - } - - @Override - public String toString() { - return "DestinationType: " + destinationType + ", DestinationName:" + destinationName + - ", Url: " + url + ", scheme: " + scheme + ", Host: " + host + ", Port: " + - port + ", Path: " + path + ", Method: " + method + ", Message: " + message; - } - - public static class Builder { - private String message; - private DestinationType destinationType; - private String destinationName; - private String url; - private String scheme; - private String host; - private Integer port; - private String path; - private String method; - private Map queryParams; - private Map headerParams; - private String userName; - private String password; - - public Builder(String destinationName) { - this.destinationName = destinationName; - this.destinationType = DestinationType.CUSTOMWEBHOOK; - } - - public CustomWebhookMessage.Builder withScheme(String scheme) { - this.scheme = scheme; - return this; - } - - public CustomWebhookMessage.Builder withHost(String host) { - this.host = host; - return this; - } - - public CustomWebhookMessage.Builder withPort(Integer port) { - this.port = port; - return this; - } - - public CustomWebhookMessage.Builder withPath(String path) { - this.path = path; - return this; - } - - public CustomWebhookMessage.Builder withMethod(String method) { - this.method = method; - return this; - } - - public CustomWebhookMessage.Builder withQueryParams(Map queryParams) { - this.queryParams = queryParams; - return this; - } - - public CustomWebhookMessage.Builder withHeaderParams(Map headerParams) { - this.headerParams = headerParams; - return this; - } - - public CustomWebhookMessage.Builder withMessage(String message) { - this.message = message; - return this; - } - - public CustomWebhookMessage.Builder withUrl(String url) { - this.url = url; - return this; - } - - public CustomWebhookMessage.Builder withUserName(String userName) { - this.userName = userName; - return this; - } - - public CustomWebhookMessage.Builder withPassword(String password) { - this.password = password; - return this; - } - - public CustomWebhookMessage build() { - CustomWebhookMessage customWebhookMessage = new CustomWebhookMessage( - this.destinationType, this.destinationName, this.url, - this.scheme, this.host, this.port, this.path, this.method, this.queryParams, - this.headerParams, this.userName, this.password, this.message); - return customWebhookMessage; - } - } - - public String getScheme() { - return scheme; - } - - public String getHost() { - return host; - } - - public int getPort() { - return port; - } - - public String getPath() { - return path; - } - - public String getMethod() { return method; } - - public Map getQueryParams() { - return queryParams; - } - - public Map getHeaderParams() { - return headerParams; - } - - public URI getUri() { - return buildUri(getUrl(), getScheme(), getHost(), getPort(), getPath(), getQueryParams()); - } -} \ No newline at end of file diff --git a/notification/src/main/java/org/opensearch/alerting/destination/message/DestinationType.java b/notification/src/main/java/org/opensearch/alerting/destination/message/DestinationType.java deleted file mode 100644 index 30d74eb2d..000000000 --- a/notification/src/main/java/org/opensearch/alerting/destination/message/DestinationType.java +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.opensearch.alerting.destination.message; - -/** - * Supported notification destinations - */ -public enum DestinationType { - CHIME, SLACK, CUSTOMWEBHOOK, EMAIL -} diff --git a/notification/src/main/java/org/opensearch/alerting/destination/message/EmailMessage.java b/notification/src/main/java/org/opensearch/alerting/destination/message/EmailMessage.java deleted file mode 100644 index 65e7a35b6..000000000 --- a/notification/src/main/java/org/opensearch/alerting/destination/message/EmailMessage.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.opensearch.alerting.destination.message; - -import org.opensearch.common.Strings; -import org.opensearch.common.settings.SecureString; - -import java.net.URI; -import java.util.List; - -/** - * This class holds the content of an Email message - */ -public class EmailMessage extends BaseMessage { - - private String message; - private String host; - private int port; - private String method; - private String from; - private List recipients; - private String subject; - private final SecureString username; - private final SecureString password; - - private EmailMessage(final DestinationType destinationType, - final String destinationName, - final String host, - final Integer port, - final String method, - final String from, - final List recipients, - final String subject, - final SecureString username, - final SecureString password, - final String message) { - - super(destinationType, destinationName, message); - - if (DestinationType.EMAIL != destinationType) { - throw new IllegalArgumentException("Channel Type does not match Email"); - } - - if (Strings.isNullOrEmpty(message)) { - throw new IllegalArgumentException("Message content is missing"); - } - - if(Strings.isNullOrEmpty(host)) { - throw new IllegalArgumentException("Host name should be provided"); - } - - if(Strings.isNullOrEmpty(from)) { - throw new IllegalArgumentException("From address should be provided"); - } - - if(recipients == null || recipients.isEmpty()) { - throw new IllegalArgumentException("List of recipients should be provided"); - } - - this.message = message; - this.host = host; - this.port = port == null ? 25 : port; - this.method = method == null ? "none" : method; - this.from = from; - this.recipients = recipients; - this.subject = subject == "" ? destinationName : subject; - this.username = username; - this.password = password; - } - - @Override - public String toString() { - return "DestinationType: " + destinationType + ", DestinationName: " + destinationName + - ", Host: " + host + ", Port: " + port + ", Message: " + message; - } - - public static class Builder { - private String message; - private DestinationType destinationType; - private String destinationName; - private String host; - private Integer port; - private String method; - private String from; - private List recipients; - private String subject; - private SecureString username; - private SecureString password; - - public Builder(String destinationName) { - this.destinationName = destinationName; - this.destinationType = DestinationType.EMAIL; - } - - public EmailMessage.Builder withHost(String host) { - this.host = host; - return this; - } - - public EmailMessage.Builder withPort(Integer port) { - this.port = port; - return this; - } - - public EmailMessage.Builder withMethod(String method) { - this.method = method; - return this; - } - - public EmailMessage.Builder withFrom(String from) { - this.from = from; - return this; - } - - public EmailMessage.Builder withRecipients(List recipients) { - this.recipients = recipients; - return this; - } - - public EmailMessage.Builder withSubject(String subject) { - this.subject = subject; - return this; - } - - public EmailMessage.Builder withMessage(String message) { - this.message = message; - return this; - } - - public EmailMessage.Builder withUserName(SecureString username) { - this.username = username; - return this; - } - - public EmailMessage.Builder withPassword(SecureString password) { - this.password = password; - return this; - } - - public EmailMessage build() { - return new EmailMessage( - this.destinationType, this.destinationName, - this.host, this.port, this.method, - this.from, this.recipients, this.subject, - this.username, this.password, this.message); - } - } - - public String getHost() { return host; } - - public int getPort() { - return port; - } - - public String getMethod() { - return method; - } - - public String getFrom() { - return from; - } - - public List getRecipients() { - return recipients; - } - - public String getSubject() { - return subject; - } - - public SecureString getUsername() { - return username; - } - - public SecureString getPassword() { - return password; - } - - public URI getUri() { - return buildUri(null, null, host, port, null, null); - } -} \ No newline at end of file diff --git a/notification/src/main/java/org/opensearch/alerting/destination/message/SlackMessage.java b/notification/src/main/java/org/opensearch/alerting/destination/message/SlackMessage.java deleted file mode 100644 index fb48e9593..000000000 --- a/notification/src/main/java/org/opensearch/alerting/destination/message/SlackMessage.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.opensearch.alerting.destination.message; - -import org.opensearch.common.Strings; - -/** - * This class holds the content of an Slack message - */ -public class SlackMessage extends BaseMessage { - private String message; - private SlackMessage(final DestinationType destinationType, - final String destinationName, - final String url, - final String message) { - - super(destinationType, destinationName, message, url); - - if (DestinationType.SLACK != destinationType) { - throw new IllegalArgumentException("Channel Type does not match Slack"); - } - - if (Strings.isNullOrEmpty(url)) { // add URL validation - throw new IllegalArgumentException("Fully qualified URL is missing/invalid: " + url); - } - - if (Strings.isNullOrEmpty(message)) { - throw new IllegalArgumentException("Message content is missing"); - } - - this.message = message; - } - - @Override - public String toString() { - return "DestinationType: " + destinationType + ", DestinationName:" + destinationName + - ", Url: " + url + ", Message: " + message; - } - - public static class Builder { - private String message; - private DestinationType destinationType; - private String destinationName; - private String url; - - public Builder(String channelName) { - this.destinationName = channelName; - this.destinationType = DestinationType.SLACK; - } - - public SlackMessage.Builder withMessage(String message) { - this.message = message; - return this; - } - - public SlackMessage.Builder withUrl(String url) { - this.url = url; - return this; - } - - public SlackMessage build() { - SlackMessage slackMessage = new SlackMessage(this.destinationType, - this.destinationName, - this.url, - this.message); - return slackMessage; - } - } - - public String getMessage() { - return message; - } - - public String getUrl() { - return url; - } -} diff --git a/notification/src/main/java/org/opensearch/alerting/destination/response/BaseResponse.java b/notification/src/main/java/org/opensearch/alerting/destination/response/BaseResponse.java deleted file mode 100644 index 8d2c7acda..000000000 --- a/notification/src/main/java/org/opensearch/alerting/destination/response/BaseResponse.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.opensearch.alerting.destination.response; - -/** - * This class holds the generic response attributes - */ -public abstract class BaseResponse { - protected Integer statusCode; - - BaseResponse(final Integer statusCode) { - if (statusCode == null) { - throw new IllegalArgumentException("status code is invalid"); - } - this.statusCode = statusCode; - } - - public int getStatusCode() { - return statusCode; - } -} diff --git a/notification/src/main/java/org/opensearch/alerting/destination/response/DestinationResponse.java b/notification/src/main/java/org/opensearch/alerting/destination/response/DestinationResponse.java deleted file mode 100644 index 9272f236e..000000000 --- a/notification/src/main/java/org/opensearch/alerting/destination/response/DestinationResponse.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.opensearch.alerting.destination.response; - -/** - * This class is a place holder for destination response metadata - */ -public class DestinationResponse extends BaseResponse { - - private String responseContent; - - private DestinationResponse(final String responseString, final int statusCode) { - super(statusCode); - if (responseString == null) { - throw new IllegalArgumentException("Response is missing"); - } - this.responseContent = responseString; - } - - public static class Builder { - private String responseContent; - private Integer statusCode = null; - - public DestinationResponse.Builder withResponseContent(String responseContent) { - this.responseContent = responseContent; - return this; - } - - public DestinationResponse.Builder withStatusCode(Integer statusCode) { - this.statusCode = statusCode; - return this; - } - - public DestinationResponse build() { - return new DestinationResponse(responseContent, statusCode); - } - } - - public String getResponseContent() { - return this.responseContent; - } -} diff --git a/notification/src/test/java/org/opensearch/alerting/destination/ChimeDestinationTest.java b/notification/src/test/java/org/opensearch/alerting/destination/ChimeDestinationTest.java deleted file mode 100644 index 1011232a5..000000000 --- a/notification/src/test/java/org/opensearch/alerting/destination/ChimeDestinationTest.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.opensearch.alerting.destination; - -import org.opensearch.alerting.destination.client.DestinationHttpClient; -import org.opensearch.alerting.destination.factory.ChimeDestinationFactory; -import org.opensearch.alerting.destination.factory.DestinationFactoryProvider; -import org.opensearch.alerting.destination.message.BaseMessage; -import org.opensearch.alerting.destination.message.ChimeMessage; -import org.opensearch.alerting.destination.message.DestinationType; -import org.opensearch.alerting.destination.response.DestinationResponse; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.message.BasicStatusLine; -import org.easymock.EasyMock; -import org.opensearch.rest.RestStatus; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; - -public class ChimeDestinationTest { - - @Test - public void testChimeMessage_NullEntityResponse() throws Exception { - CloseableHttpClient mockHttpClient = EasyMock.createMock(CloseableHttpClient.class); - - // The DestinationHttpClient replaces a null entity with "{}". - DestinationResponse expectedChimeResponse = new DestinationResponse.Builder() - .withResponseContent("{}") - .withStatusCode(RestStatus.OK.getStatus()) - .build(); - CloseableHttpResponse httpResponse = EasyMock.createMock(CloseableHttpResponse.class); - EasyMock.expect(mockHttpClient.execute(EasyMock.anyObject(HttpPost.class))).andReturn(httpResponse); - - BasicStatusLine mockStatusLine = EasyMock.createMock(BasicStatusLine.class); - - EasyMock.expect(httpResponse.getStatusLine()).andReturn(mockStatusLine); - EasyMock.expect(httpResponse.getEntity()).andReturn(null).anyTimes(); - EasyMock.expect(mockStatusLine.getStatusCode()).andReturn(RestStatus.OK.getStatus()); - EasyMock.replay(mockHttpClient); - EasyMock.replay(httpResponse); - EasyMock.replay(mockStatusLine); - - DestinationHttpClient httpClient = new DestinationHttpClient(); - httpClient.setHttpClient(mockHttpClient); - ChimeDestinationFactory chimeDestinationFactory = new ChimeDestinationFactory(); - chimeDestinationFactory.setClient(httpClient); - - DestinationFactoryProvider.setFactory(DestinationType.CHIME, chimeDestinationFactory); - - String message = "{\"Content\":\"Message gughjhjlkh Body emoji test: :) :+1: " + - "link test: http://sample.com email test: marymajor@example.com All member callout: " + - "@All All Present member callout: @Present\"}"; - BaseMessage bm = new ChimeMessage.Builder("abc").withMessage(message). - withUrl("https://abc/com").build(); - DestinationResponse actualChimeResponse = (DestinationResponse) Notification.publish(bm); - - assertEquals(expectedChimeResponse.getResponseContent(), actualChimeResponse.getResponseContent()); - assertEquals(expectedChimeResponse.getStatusCode(), actualChimeResponse.getStatusCode()); - } - - @Test - public void testChimeMessage_EmptyEntityResponse() throws Exception { - CloseableHttpClient mockHttpClient = EasyMock.createMock(CloseableHttpClient.class); - - DestinationResponse expectedChimeResponse = new DestinationResponse.Builder() - .withResponseContent("") - .withStatusCode(RestStatus.OK.getStatus()) - .build(); - CloseableHttpResponse httpResponse = EasyMock.createMock(CloseableHttpResponse.class); - EasyMock.expect(mockHttpClient.execute(EasyMock.anyObject(HttpPost.class))).andReturn(httpResponse); - - BasicStatusLine mockStatusLine = EasyMock.createMock(BasicStatusLine.class); - - EasyMock.expect(httpResponse.getStatusLine()).andReturn(mockStatusLine); - EasyMock.expect(httpResponse.getEntity()).andReturn(new StringEntity("")).anyTimes(); - EasyMock.expect(mockStatusLine.getStatusCode()).andReturn(RestStatus.OK.getStatus()); - EasyMock.replay(mockHttpClient); - EasyMock.replay(httpResponse); - EasyMock.replay(mockStatusLine); - - DestinationHttpClient httpClient = new DestinationHttpClient(); - httpClient.setHttpClient(mockHttpClient); - ChimeDestinationFactory chimeDestinationFactory = new ChimeDestinationFactory(); - chimeDestinationFactory.setClient(httpClient); - - DestinationFactoryProvider.setFactory(DestinationType.CHIME, chimeDestinationFactory); - - String message = "{\"Content\":\"Message gughjhjlkh Body emoji test: :) :+1: " + - "link test: http://sample.com email test: marymajor@example.com All member callout: " + - "@All All Present member callout: @Present\"}"; - BaseMessage bm = new ChimeMessage.Builder("abc").withMessage(message). - withUrl("https://abc/com").build(); - DestinationResponse actualChimeResponse = (DestinationResponse) Notification.publish(bm); - - assertEquals(expectedChimeResponse.getResponseContent(), actualChimeResponse.getResponseContent()); - assertEquals(expectedChimeResponse.getStatusCode(), actualChimeResponse.getStatusCode()); - } - - @Test - public void testChimeMessage_NonemptyEntityResponse() throws Exception { - String responseContent = "It worked!"; - - CloseableHttpClient mockHttpClient = EasyMock.createMock(CloseableHttpClient.class); - - DestinationResponse expectedChimeResponse = new DestinationResponse.Builder().withResponseContent(responseContent) - .withStatusCode(RestStatus.OK.getStatus()).build(); - CloseableHttpResponse httpResponse = EasyMock.createMock(CloseableHttpResponse.class); - EasyMock.expect(mockHttpClient.execute(EasyMock.anyObject(HttpPost.class))).andReturn(httpResponse); - - BasicStatusLine mockStatusLine = EasyMock.createMock(BasicStatusLine.class); - - EasyMock.expect(httpResponse.getStatusLine()).andReturn(mockStatusLine); - EasyMock.expect(httpResponse.getEntity()).andReturn(new StringEntity(responseContent)).anyTimes(); - EasyMock.expect(mockStatusLine.getStatusCode()).andReturn(RestStatus.OK.getStatus()); - EasyMock.replay(mockHttpClient); - EasyMock.replay(httpResponse); - EasyMock.replay(mockStatusLine); - - DestinationHttpClient httpClient = new DestinationHttpClient(); - httpClient.setHttpClient(mockHttpClient); - ChimeDestinationFactory chimeDestinationFactory = new ChimeDestinationFactory(); - chimeDestinationFactory.setClient(httpClient); - - DestinationFactoryProvider.setFactory(DestinationType.CHIME, chimeDestinationFactory); - - String message = "{\"Content\":\"Message gughjhjlkh Body emoji test: :) :+1: " + - "link test: http://sample.com email test: marymajor@example.com All member callout: " + - "@All All Present member callout: @Present\"}"; - BaseMessage bm = new ChimeMessage.Builder("abc").withMessage(message). - withUrl("https://abc/com").build(); - DestinationResponse actualChimeResponse = (DestinationResponse) Notification.publish(bm); - - assertEquals(expectedChimeResponse.getResponseContent(), actualChimeResponse.getResponseContent()); - assertEquals(expectedChimeResponse.getStatusCode(), actualChimeResponse.getStatusCode()); - } - - @Test(expected = IllegalArgumentException.class) - public void testUrlMissingMessage() { - try { - ChimeMessage message = new ChimeMessage.Builder("chime") - .withMessage("dummyMessage").build(); - } catch (Exception ex) { - assertEquals("url is invalid or empty", ex.getMessage()); - throw ex; - } - } - - @Test(expected = IllegalArgumentException.class) - public void testContentMissingMessage() { - try { - ChimeMessage message = new ChimeMessage.Builder("chime") - .withUrl("abc.com").build(); - } catch (Exception ex) { - assertEquals("Message content is missing", ex.getMessage()); - throw ex; - } - } -} diff --git a/notification/src/test/java/org/opensearch/alerting/destination/CustomWebhookMessageTest.java b/notification/src/test/java/org/opensearch/alerting/destination/CustomWebhookMessageTest.java deleted file mode 100644 index d27c5c71f..000000000 --- a/notification/src/test/java/org/opensearch/alerting/destination/CustomWebhookMessageTest.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.opensearch.alerting.destination; - -import org.opensearch.alerting.destination.client.DestinationHttpClient; -import org.opensearch.alerting.destination.factory.CustomWebhookDestinationFactory; -import org.opensearch.alerting.destination.factory.DestinationFactoryProvider; -import org.opensearch.alerting.destination.message.BaseMessage; -import org.opensearch.alerting.destination.message.CustomWebhookMessage; -import org.opensearch.alerting.destination.message.DestinationType; -import org.opensearch.alerting.destination.response.DestinationResponse; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpPatch; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.client.methods.HttpPut; -import org.apache.http.client.methods.HttpUriRequest; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.message.BasicStatusLine; -import org.easymock.EasyMock; -import org.opensearch.rest.RestStatus; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; - -import java.util.HashMap; -import java.util.Map; - -import static org.junit.Assert.assertEquals; - - -@RunWith(Parameterized.class) -public class CustomWebhookMessageTest { - @Parameterized.Parameters(name = "Param: {0}={1}") - public static Object[][] params() { - return new Object[][]{ - {"POST", HttpPost.class}, - {"PUT", HttpPut.class}, - {"PATCH", HttpPatch.class}, - }; - } - - @Parameterized.Parameter(0) - public String method; - - @Parameterized.Parameter(1) - public Class expectedHttpClass; - - @Test - public void testCustomWebhookMessage_NullEntityResponse() throws Exception { - CloseableHttpClient mockHttpClient = EasyMock.createMock(CloseableHttpClient.class); - - // The DestinationHttpClient replaces a null entity with "{}". - DestinationResponse expectedCustomWebhookResponse = new DestinationResponse.Builder() - .withResponseContent("{}") - .withStatusCode(RestStatus.OK.getStatus()) - .build(); - CloseableHttpResponse httpResponse = EasyMock.createMock(CloseableHttpResponse.class); - EasyMock.expect(mockHttpClient.execute(EasyMock.anyObject(HttpPost.class))).andReturn(httpResponse); - EasyMock.expect(mockHttpClient.execute(EasyMock.isA(expectedHttpClass))).andReturn(httpResponse); - - BasicStatusLine mockStatusLine = EasyMock.createMock(BasicStatusLine.class); - - EasyMock.expect(httpResponse.getStatusLine()).andReturn(mockStatusLine); - EasyMock.expect(httpResponse.getEntity()).andReturn(null).anyTimes(); - EasyMock.expect(mockStatusLine.getStatusCode()).andReturn(RestStatus.OK.getStatus()); - EasyMock.replay(mockHttpClient); - EasyMock.replay(httpResponse); - EasyMock.replay(mockStatusLine); - - DestinationHttpClient httpClient = new DestinationHttpClient(); - httpClient.setHttpClient(mockHttpClient); - CustomWebhookDestinationFactory customDestinationFactory = new CustomWebhookDestinationFactory(); - customDestinationFactory.setClient(httpClient); - - DestinationFactoryProvider.setFactory(DestinationType.CUSTOMWEBHOOK, customDestinationFactory); - - Map queryParams = new HashMap(); - queryParams.put("token", "R2x1UlN4ZHF8MXxxVFJpelJNVDgzdGNwMnVRenJwRFBHUkR0NlhROWhXOVVTZXpiTWx2azVr"); - - String message = "{\"Content\":\"Message gughjhjlkh Body emoji test: :) :+1: " + - "link test: http://sample.com email test: marymajor@example.com " + - "All member callout: @All All Present member callout: @Present\"}"; - BaseMessage bm = new CustomWebhookMessage.Builder("abc").withHost("hooks.chime.aws"). - withPath("incomingwebhooks/383c0e2b-d028-44f4-8d38-696754bc4574"). - withMessage(message).withMethod(method). - withQueryParams(queryParams).build(); - DestinationResponse actualCustomResponse = (DestinationResponse) Notification.publish(bm); - - assertEquals(expectedCustomWebhookResponse.getResponseContent(), actualCustomResponse.getResponseContent()); - assertEquals(expectedCustomWebhookResponse.getStatusCode(), actualCustomResponse.getStatusCode()); - } - - @Test - public void testCustomWebhookMessage_EmptyEntityResponse() throws Exception { - CloseableHttpClient mockHttpClient = EasyMock.createMock(CloseableHttpClient.class); - - DestinationResponse expectedCustomWebhookResponse = new DestinationResponse.Builder() - .withResponseContent("") - .withStatusCode(RestStatus.OK.getStatus()) - .build(); - CloseableHttpResponse httpResponse = EasyMock.createMock(CloseableHttpResponse.class); - EasyMock.expect(mockHttpClient.execute(EasyMock.isA(expectedHttpClass))).andReturn(httpResponse); - - BasicStatusLine mockStatusLine = EasyMock.createMock(BasicStatusLine.class); - - EasyMock.expect(httpResponse.getStatusLine()).andReturn(mockStatusLine); - EasyMock.expect(httpResponse.getEntity()).andReturn(new StringEntity("")).anyTimes(); - EasyMock.expect(mockStatusLine.getStatusCode()).andReturn(RestStatus.OK.getStatus()); - EasyMock.replay(mockHttpClient); - EasyMock.replay(httpResponse); - EasyMock.replay(mockStatusLine); - - DestinationHttpClient httpClient = new DestinationHttpClient(); - httpClient.setHttpClient(mockHttpClient); - CustomWebhookDestinationFactory customDestinationFactory = new CustomWebhookDestinationFactory(); - customDestinationFactory.setClient(httpClient); - - DestinationFactoryProvider.setFactory(DestinationType.CUSTOMWEBHOOK, customDestinationFactory); - - Map queryParams = new HashMap(); - queryParams.put("token", "R2x1UlN4ZHF8MXxxVFJpelJNVDgzdGNwMnVRenJwRFBHUkR0NlhROWhXOVVTZXpiTWx2azVr"); - - String message = "{\"Content\":\"Message gughjhjlkh Body emoji test: :) :+1: " + - "link test: http://sample.com email test: marymajor@example.com " + - "All member callout: @All All Present member callout: @Present\"}"; - BaseMessage bm = new CustomWebhookMessage.Builder("abc").withHost("hooks.chime.aws"). - withPath("incomingwebhooks/383c0e2b-d028-44f4-8d38-696754bc4574"). - withMessage(message).withMethod(method). - withQueryParams(queryParams).build(); - DestinationResponse actualCustomResponse = (DestinationResponse) Notification.publish(bm); - - assertEquals(expectedCustomWebhookResponse.getResponseContent(), actualCustomResponse.getResponseContent()); - assertEquals(expectedCustomWebhookResponse.getStatusCode(), actualCustomResponse.getStatusCode()); - } - - @Test - public void testCustomWebhookMessage_NonemptyEntityResponse() throws Exception { - String responseContent = "It worked!"; - - CloseableHttpClient mockHttpClient = EasyMock.createMock(CloseableHttpClient.class); - - DestinationResponse expectedCustomWebhookResponse = new DestinationResponse.Builder() - .withResponseContent(responseContent) - .withStatusCode(RestStatus.OK.getStatus()) - .build(); - CloseableHttpResponse httpResponse = EasyMock.createMock(CloseableHttpResponse.class); - EasyMock.expect(mockHttpClient.execute(EasyMock.isA(expectedHttpClass))).andReturn(httpResponse); - - BasicStatusLine mockStatusLine = EasyMock.createMock(BasicStatusLine.class); - - EasyMock.expect(httpResponse.getStatusLine()).andReturn(mockStatusLine); - EasyMock.expect(httpResponse.getEntity()).andReturn(new StringEntity(responseContent)).anyTimes(); - EasyMock.expect(mockStatusLine.getStatusCode()).andReturn(RestStatus.OK.getStatus()); - EasyMock.replay(mockHttpClient); - EasyMock.replay(httpResponse); - EasyMock.replay(mockStatusLine); - - DestinationHttpClient httpClient = new DestinationHttpClient(); - httpClient.setHttpClient(mockHttpClient); - CustomWebhookDestinationFactory customDestinationFactory = new CustomWebhookDestinationFactory(); - customDestinationFactory.setClient(httpClient); - - DestinationFactoryProvider.setFactory(DestinationType.CUSTOMWEBHOOK, customDestinationFactory); - - Map queryParams = new HashMap(); - queryParams.put("token", "R2x1UlN4ZHF8MXxxVFJpelJNVDgzdGNwMnVRenJwRFBHUkR0NlhROWhXOVVTZXpiTWx2azVr"); - - String message = "{\"Content\":\"Message gughjhjlkh Body emoji test: :) :+1: " + - "link test: http://sample.com email test: marymajor@example.com " + - "All member callout: @All All Present member callout: @Present\"}"; - BaseMessage bm = new CustomWebhookMessage.Builder("abc").withHost("hooks.chime.aws"). - withPath("incomingwebhooks/383c0e2b-d028-44f4-8d38-696754bc4574"). - withMessage(message).withMethod(method). - withQueryParams(queryParams).build(); - DestinationResponse actualCustomResponse = (DestinationResponse) Notification.publish(bm); - - assertEquals(expectedCustomWebhookResponse.getResponseContent(), actualCustomResponse.getResponseContent()); - assertEquals(expectedCustomWebhookResponse.getStatusCode(), actualCustomResponse.getStatusCode()); - } - - @Test(expected = IllegalArgumentException.class) - public void testUrlMissingMessage() { - try { - CustomWebhookMessage message = new CustomWebhookMessage.Builder("custom") - .withMessage("dummyMessage").build(); - } catch (Exception ex) { - assertEquals("Either fully qualified URL or host name should be provided", ex.getMessage()); - throw ex; - } - } - - @Test(expected = IllegalArgumentException.class) - public void testContentMissingMessage() { - try { - CustomWebhookMessage message = new CustomWebhookMessage.Builder("custom") - .withUrl("abc.com").build(); - } catch (Exception ex) { - assertEquals("Message content is missing", ex.getMessage()); - throw ex; - } - } -} diff --git a/notification/src/test/java/org/opensearch/alerting/destination/EmailDestinationTest.java b/notification/src/test/java/org/opensearch/alerting/destination/EmailDestinationTest.java deleted file mode 100644 index 9d277c6ed..000000000 --- a/notification/src/test/java/org/opensearch/alerting/destination/EmailDestinationTest.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.opensearch.alerting.destination; - -import org.opensearch.alerting.destination.factory.DestinationFactoryProvider; -import org.opensearch.alerting.destination.factory.EmailDestinationFactory; -import org.opensearch.alerting.destination.message.BaseMessage; -import org.opensearch.alerting.destination.message.DestinationType; -import org.opensearch.alerting.destination.message.EmailMessage; -import org.opensearch.alerting.destination.client.DestinationEmailClient; -import org.opensearch.alerting.destination.response.DestinationResponse; -import org.easymock.EasyMock; -import org.opensearch.common.settings.SecureString; -import org.junit.Assert; -import org.junit.Test; -import javax.mail.Message; -import javax.mail.MessagingException; - -import static java.util.Collections.singletonList; -import static org.junit.Assert.assertEquals; - -public class EmailDestinationTest { - - @Test - public void testMailMessage() throws Exception { - - DestinationResponse expectedEmailResponse = new DestinationResponse.Builder() - .withResponseContent("Sent") - .withStatusCode(0).build(); - - DestinationEmailClient emailClient = EasyMock.partialMockBuilder(DestinationEmailClient.class) - .addMockedMethod("SendMessage").createMock(); - emailClient.SendMessage(EasyMock.anyObject(Message.class)); - - EmailDestinationFactory emailDestinationFactory = new EmailDestinationFactory(); - emailDestinationFactory.setClient(emailClient); - - DestinationFactoryProvider.setFactory(DestinationType.EMAIL, emailDestinationFactory); - - String message = "{\"text\":\"Vamshi Message gughjhjlkh Body emoji test: :) :+1: " + - "link test: http://sample.com email test: marymajor@example.com All member callout: " + - "@All All Present member callout: @Present\"}"; - BaseMessage bm = new EmailMessage.Builder("abc") - .withMessage(message) - .withHost("abc.com") - .withPort(465) - .withFrom("test@abc.com") - .withMethod("ssl") - .withSubject("Test") - .withMessage("Test alert") - .withRecipients(singletonList("test@abc.com")).build(); - - DestinationResponse actualEmailResponse = (DestinationResponse) Notification.publish(bm); - assertEquals(expectedEmailResponse.getResponseContent(), actualEmailResponse.getResponseContent()); - assertEquals(expectedEmailResponse.getStatusCode(), actualEmailResponse.getStatusCode()); - } - - @Test - public void testMailMessageWithAuth() throws Exception { - - DestinationResponse expectedEmailResponse = new DestinationResponse.Builder() - .withResponseContent("Sent") - .withStatusCode(0).build(); - - DestinationEmailClient emailClient = EasyMock.partialMockBuilder(DestinationEmailClient.class) - .addMockedMethod("SendMessage").createMock(); - emailClient.SendMessage(EasyMock.anyObject(Message.class)); - - EmailDestinationFactory emailDestinationFactory = new EmailDestinationFactory(); - emailDestinationFactory.setClient(emailClient); - - DestinationFactoryProvider.setFactory(DestinationType.EMAIL, emailDestinationFactory); - - String message = "{\"text\":\"Vamshi Message gughjhjlkh Body emoji test: :) :+1: " + - "link test: http://sample.com email test: marymajor@example.com All member callout: " + - "@All All Present member callout: @Present\"}"; - SecureString username = new SecureString("user1".toCharArray()); - SecureString password = new SecureString("password".toCharArray()); - BaseMessage bm = new EmailMessage.Builder("abc") - .withMessage(message) - .withHost("abc.com") - .withPort(465) - .withFrom("test@abc.com") - .withMethod("ssl") - .withSubject("Test") - .withMessage("Test alert") - .withUserName(username) - .withPassword(password) - .withRecipients(singletonList("test@abc.com")).build(); - - DestinationResponse actualEmailResponse = (DestinationResponse) Notification.publish(bm); - assertEquals(expectedEmailResponse.getResponseContent(), actualEmailResponse.getResponseContent()); - assertEquals(expectedEmailResponse.getStatusCode(), actualEmailResponse.getStatusCode()); - } - - @Test(expected = IllegalStateException.class) - public void testFailingMailMessage() throws Exception { - - DestinationResponse expectedEmailResponse = new DestinationResponse.Builder() - .withResponseContent("Couldn't connect to host, port: localhost, 55555; timeout -1") - .withStatusCode(1).build(); - - DestinationEmailClient emailClient = EasyMock.partialMockBuilder(DestinationEmailClient.class) - .addMockedMethod("SendMessage").createMock(); - emailClient.SendMessage(EasyMock.anyObject(Message.class)); - EasyMock.expectLastCall() - .andThrow(new MessagingException("Couldn't connect to host, port: localhost, 55555; timeout -1")); - EasyMock.replay(emailClient); - - EmailDestinationFactory emailDestinationFactory = new EmailDestinationFactory(); - emailDestinationFactory.setClient(emailClient); - - DestinationFactoryProvider.setFactory(DestinationType.EMAIL, emailDestinationFactory); - - String message = "{\"text\":\"Vamshi Message gughjhjlkh Body emoji test: :) :+1: " + - "link test: http://sample.com email test: marymajor@example.com All member callout: " + - "@All All Present member callout: @Present\"}"; - BaseMessage bm = new EmailMessage.Builder("abc") - .withMessage(message) - .withHost("localhost") - .withPort(55555) - .withFrom("test@abc.com") - .withRecipients(singletonList("test@abc.com")).build(); - - DestinationResponse actualEmailResponse = (DestinationResponse) Notification.publish(bm); - EasyMock.verify(emailClient); - assertEquals(expectedEmailResponse.getResponseContent(), actualEmailResponse.getResponseContent()); - assertEquals(expectedEmailResponse.getStatusCode(), actualEmailResponse.getStatusCode()); - } - - @Test(expected = IllegalArgumentException.class) - public void testHostMissingMessage() { - try { - EmailMessage message = new EmailMessage.Builder("mail") - .withMessage("dummyMessage") - .withFrom("test@abc.com") - .withRecipients(singletonList("test@abc.com")).build(); - - } catch (Exception ex) { - Assert.assertEquals("Host name should be provided", ex.getMessage()); - throw ex; - } - } - - @Test(expected = IllegalArgumentException.class) - public void testContentMissingMessage() { - try { - EmailMessage message = new EmailMessage.Builder("mail") - .withHost("abc.com") - .withFrom("test@abc.com") - .withRecipients(singletonList("test@abc.com")).build(); - } catch (Exception ex) { - assertEquals("Message content is missing", ex.getMessage()); - throw ex; - } - } - - @Test(expected = IllegalArgumentException.class) - public void testFromMissingMessage() { - try { - EmailMessage message = new EmailMessage.Builder("mail") - .withMessage("dummyMessage") - .withHost("abc.com") - .withRecipients(singletonList("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 { - EmailMessage message = new EmailMessage.Builder("mail") - .withMessage("dummyMessage") - .withHost("abc.com") - .withFrom("test@abc.com").build(); - - } catch (Exception ex) { - Assert.assertEquals("List of recipients should be provided", ex.getMessage()); - throw ex; - } - } -} diff --git a/notification/src/test/java/org/opensearch/alerting/destination/SlackDestinationTest.java b/notification/src/test/java/org/opensearch/alerting/destination/SlackDestinationTest.java deleted file mode 100644 index 56069f566..000000000 --- a/notification/src/test/java/org/opensearch/alerting/destination/SlackDestinationTest.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.opensearch.alerting.destination; - -import org.opensearch.alerting.destination.client.DestinationHttpClient; -import org.opensearch.alerting.destination.factory.DestinationFactoryProvider; -import org.opensearch.alerting.destination.factory.SlackDestinationFactory; -import org.opensearch.alerting.destination.message.BaseMessage; -import org.opensearch.alerting.destination.message.DestinationType; -import org.opensearch.alerting.destination.message.SlackMessage; -import org.opensearch.alerting.destination.response.DestinationResponse; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.message.BasicStatusLine; -import org.easymock.EasyMock; -import org.opensearch.rest.RestStatus; -import org.junit.Assert; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; - -public class SlackDestinationTest { - - @Test - public void testSlackMessage_NullEntityResponse() throws Exception { - CloseableHttpClient mockHttpClient = EasyMock.createMock(CloseableHttpClient.class); - - // The DestinationHttpClient replaces a null entity with "{}". - DestinationResponse expectedSlackResponse = new DestinationResponse.Builder() - .withResponseContent("{}") - .withStatusCode(RestStatus.OK.getStatus()) - .build(); - CloseableHttpResponse httpResponse = EasyMock.createMock(CloseableHttpResponse.class); - EasyMock.expect(mockHttpClient.execute(EasyMock.anyObject(HttpPost.class))).andReturn(httpResponse); - - BasicStatusLine mockStatusLine = EasyMock.createMock(BasicStatusLine.class); - - EasyMock.expect(httpResponse.getStatusLine()).andReturn(mockStatusLine); - EasyMock.expect(httpResponse.getEntity()).andReturn(null).anyTimes(); - EasyMock.expect(mockStatusLine.getStatusCode()).andReturn(RestStatus.OK.getStatus()); - EasyMock.replay(mockHttpClient); - EasyMock.replay(httpResponse); - EasyMock.replay(mockStatusLine); - - DestinationHttpClient httpClient = new DestinationHttpClient(); - httpClient.setHttpClient(mockHttpClient); - SlackDestinationFactory slackDestinationFactory = new SlackDestinationFactory(); - slackDestinationFactory.setClient(httpClient); - - DestinationFactoryProvider.setFactory(DestinationType.SLACK, slackDestinationFactory); - - String message = "{\"text\":\"Vamshi Message gughjhjlkh Body emoji test: :) :+1: " + - "link test: http://sample.com email test: marymajor@example.com All member callout: " + - "@All All Present member callout: @Present\"}"; - BaseMessage bm = new SlackMessage.Builder("abc").withMessage(message). - withUrl("https://hooks.slack.com/services/xxxx/xxxxxx/xxxxxxxxx").build(); - - DestinationResponse actualSlackResponse = (DestinationResponse) Notification.publish(bm); - - assertEquals(expectedSlackResponse.getResponseContent(), actualSlackResponse.getResponseContent()); - assertEquals(expectedSlackResponse.getStatusCode(), actualSlackResponse.getStatusCode()); - } - - @Test - public void testSlackMessage_EmptyEntityResponse() throws Exception { - CloseableHttpClient mockHttpClient = EasyMock.createMock(CloseableHttpClient.class); - - DestinationResponse expectedSlackResponse = new DestinationResponse.Builder() - .withResponseContent("") - .withStatusCode(RestStatus.OK.getStatus()) - .build(); - CloseableHttpResponse httpResponse = EasyMock.createMock(CloseableHttpResponse.class); - EasyMock.expect(mockHttpClient.execute(EasyMock.anyObject(HttpPost.class))).andReturn(httpResponse); - - BasicStatusLine mockStatusLine = EasyMock.createMock(BasicStatusLine.class); - - EasyMock.expect(httpResponse.getStatusLine()).andReturn(mockStatusLine); - EasyMock.expect(httpResponse.getEntity()).andReturn(new StringEntity("")).anyTimes(); - EasyMock.expect(mockStatusLine.getStatusCode()).andReturn(RestStatus.OK.getStatus()); - EasyMock.replay(mockHttpClient); - EasyMock.replay(httpResponse); - EasyMock.replay(mockStatusLine); - - DestinationHttpClient httpClient = new DestinationHttpClient(); - httpClient.setHttpClient(mockHttpClient); - SlackDestinationFactory slackDestinationFactory = new SlackDestinationFactory(); - slackDestinationFactory.setClient(httpClient); - - DestinationFactoryProvider.setFactory(DestinationType.SLACK, slackDestinationFactory); - - String message = "{\"text\":\"Vamshi Message gughjhjlkh Body emoji test: :) :+1: " + - "link test: http://sample.com email test: marymajor@example.com All member callout: " + - "@All All Present member callout: @Present\"}"; - BaseMessage bm = new SlackMessage.Builder("abc").withMessage(message). - withUrl("https://hooks.slack.com/services/xxxx/xxxxxx/xxxxxxxxx").build(); - - DestinationResponse actualSlackResponse = (DestinationResponse) Notification.publish(bm); - - assertEquals(expectedSlackResponse.getResponseContent(), actualSlackResponse.getResponseContent()); - assertEquals(expectedSlackResponse.getStatusCode(), actualSlackResponse.getStatusCode()); - } - - @Test - public void testSlackMessage_NonemptyEntityResponse() throws Exception { - String responseContent = "It worked!"; - - CloseableHttpClient mockHttpClient = EasyMock.createMock(CloseableHttpClient.class); - - DestinationResponse expectedSlackResponse = new DestinationResponse.Builder() - .withResponseContent(responseContent) - .withStatusCode(RestStatus.OK.getStatus()) - .build(); - CloseableHttpResponse httpResponse = EasyMock.createMock(CloseableHttpResponse.class); - EasyMock.expect(mockHttpClient.execute(EasyMock.anyObject(HttpPost.class))).andReturn(httpResponse); - - BasicStatusLine mockStatusLine = EasyMock.createMock(BasicStatusLine.class); - - EasyMock.expect(httpResponse.getStatusLine()).andReturn(mockStatusLine); - EasyMock.expect(httpResponse.getEntity()).andReturn(new StringEntity(responseContent)).anyTimes(); - EasyMock.expect(mockStatusLine.getStatusCode()).andReturn(RestStatus.OK.getStatus()); - EasyMock.replay(mockHttpClient); - EasyMock.replay(httpResponse); - EasyMock.replay(mockStatusLine); - - DestinationHttpClient httpClient = new DestinationHttpClient(); - httpClient.setHttpClient(mockHttpClient); - SlackDestinationFactory slackDestinationFactory = new SlackDestinationFactory(); - slackDestinationFactory.setClient(httpClient); - - DestinationFactoryProvider.setFactory(DestinationType.SLACK, slackDestinationFactory); - - String message = "{\"text\":\"Vamshi Message gughjhjlkh Body emoji test: :) :+1: " + - "link test: http://sample.com email test: marymajor@example.com All member callout: " + - "@All All Present member callout: @Present\"}"; - BaseMessage bm = new SlackMessage.Builder("abc").withMessage(message). - withUrl("https://hooks.slack.com/services/xxxx/xxxxxx/xxxxxxxxx").build(); - - DestinationResponse actualSlackResponse = (DestinationResponse) Notification.publish(bm); - - assertEquals(expectedSlackResponse.getResponseContent(), actualSlackResponse.getResponseContent()); - assertEquals(expectedSlackResponse.getStatusCode(), actualSlackResponse.getStatusCode()); - } - - @Test(expected = IllegalArgumentException.class) - public void testUrlMissingMessage() { - try { - SlackMessage message = new SlackMessage.Builder("slack") - .withMessage("dummyMessage").build(); - } catch (Exception ex) { - Assert.assertEquals("url is invalid or empty", ex.getMessage()); - throw ex; - } - } - - @Test(expected = IllegalArgumentException.class) - public void testContentMissingMessage() { - try { - SlackMessage message = new SlackMessage.Builder("slack") - .withUrl("abc.com").build(); - } catch (Exception ex) { - assertEquals("Message content is missing", ex.getMessage()); - throw ex; - } - } -} diff --git a/scripts/build.sh b/scripts/build.sh index c2f770a53..7e3777962 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -73,11 +73,3 @@ distributions="$(dirname "${zipPath}")" echo "COPY ${distributions}/*.zip" cp ${distributions}/*.zip ./$OUTPUT/plugins - -./gradlew publishShadowPublicationToMavenLocal -Dopensearch.version=$VERSION -Dbuild.version_qualifier=$QUALIFIER -Dbuild.snapshot=$SNAPSHOT -x ktlint -./gradlew publishShadowPublicationToStagingRepository -Dopensearch.version=$VERSION -Dbuild.version_qualifier=$QUALIFIER -Dbuild.snapshot=$SNAPSHOT - -mkdir -p $OUTPUT/maven/org/opensearch -cp -r ./build/local-staging-repo/org/opensearch/. $OUTPUT/maven/org/opensearch - - diff --git a/settings.gradle b/settings.gradle index 98729193c..bd847942f 100644 --- a/settings.gradle +++ b/settings.gradle @@ -6,7 +6,5 @@ rootProject.name = 'opensearch-alerting' include 'alerting' include 'core' -include 'notification' project(":core").name = 'alerting-core' -project(":notification").name = 'alerting-notification'