Skip to content
This repository was archived by the owner on Aug 2, 2022. It is now read-only.

Commit d551e20

Browse files
committed
Allows encoding while consutring HTTP request for sending notification
1 parent 64d7265 commit d551e20

File tree

2 files changed

+60
-7
lines changed

2 files changed

+60
-7
lines changed

notification/src/main/java/com/amazon/opendistroforelasticsearch/alerting/destination/client/DestinationHttpClient.java

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.apache.http.client.methods.CloseableHttpResponse;
2424
import org.apache.http.client.methods.HttpPost;
2525
import org.apache.http.client.utils.URIBuilder;
26+
import org.apache.http.entity.ContentType;
2627
import org.apache.http.entity.StringEntity;
2728
import org.apache.http.impl.client.CloseableHttpClient;
2829
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
@@ -34,10 +35,10 @@
3435
import org.elasticsearch.common.Strings;
3536
import org.elasticsearch.common.unit.TimeValue;
3637
import org.elasticsearch.rest.RestStatus;
37-
3838
import java.io.IOException;
3939
import java.net.URI;
4040
import java.net.URISyntaxException;
41+
import java.nio.charset.StandardCharsets;
4142
import java.util.Map;
4243

4344

@@ -52,7 +53,8 @@ public class DestinationHttpClient {
5253
private static final int MAX_CONNECTIONS_PER_ROUTE = 20;
5354
private static final int TIMEOUT_MILLISECONDS = (int) TimeValue.timeValueSeconds(5).millis();
5455
private static final int SOCKET_TIMEOUT_MILLISECONDS = (int)TimeValue.timeValueSeconds(50).millis();
55-
56+
private static final String DEFAULT_CONTENT_TYPE_KEY = "Content-Type";
57+
private static final String DEFAULT_CONTENT_TYPE_VALUE = "application/json";
5658
private static CloseableHttpClient HTTP_CLIENT = createHttpClient();
5759

5860
private static CloseableHttpClient createHttpClient() {
@@ -90,6 +92,7 @@ public String execute(BaseMessage message) throws Exception {
9092
private CloseableHttpResponse getHttpResponse(BaseMessage message) throws Exception {
9193
URI uri = null;
9294
HttpPost httpPostRequest = new HttpPost();
95+
String entityContentType = DEFAULT_CONTENT_TYPE_VALUE;
9396
if (message instanceof CustomWebhookMessage) {
9497
CustomWebhookMessage customWebhookMessage = (CustomWebhookMessage) message;
9598
uri = buildUri(customWebhookMessage.getUrl(), customWebhookMessage.getScheme(), customWebhookMessage.getHost(),
@@ -98,20 +101,24 @@ private CloseableHttpResponse getHttpResponse(BaseMessage message) throws Except
98101
// set headers
99102
Map<String, String> headerParams = customWebhookMessage.getHeaderParams();
100103
if(headerParams == null || headerParams.isEmpty()) {
101-
// set default header
102-
httpPostRequest.setHeader("Content-Type", "application/json");
104+
// set default header and content Type
105+
httpPostRequest.setHeader(DEFAULT_CONTENT_TYPE_KEY, DEFAULT_CONTENT_TYPE_VALUE);
103106
} else {
104-
for (Map.Entry<String, String> e : customWebhookMessage.getHeaderParams().entrySet())
107+
for (Map.Entry<String, String> e : customWebhookMessage.getHeaderParams().entrySet()){
108+
if(e.getKey().equals(DEFAULT_CONTENT_TYPE_KEY)) {
109+
entityContentType = e.getValue();
110+
}
105111
httpPostRequest.setHeader(e.getKey(), e.getValue());
112+
}
106113
}
107114
} else {
108115
uri = buildUri(message.getUrl().trim(), null, null, -1, null, null);
109116
}
110117

111118
httpPostRequest.setURI(uri);
112-
StringEntity entity = new StringEntity(extractBody(message));
119+
StringEntity entity = new StringEntity(extractBody(message),
120+
ContentType.create(entityContentType, StandardCharsets.UTF_8));
113121
httpPostRequest.setEntity(entity);
114-
115122
return HTTP_CLIENT.execute(httpPostRequest);
116123
}
117124

notification/src/test/java/com/amazon/opendistroforelasticsearch/alerting/destination/CustomWebhookMessageTest.java

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,15 @@
2424
import com.amazon.opendistroforelasticsearch.alerting.destination.response.DestinationHttpResponse;
2525
import org.apache.http.client.methods.CloseableHttpResponse;
2626
import org.apache.http.client.methods.HttpPost;
27+
import org.apache.http.entity.ContentType;
28+
import org.apache.http.entity.StringEntity;
2729
import org.apache.http.impl.client.CloseableHttpClient;
2830
import org.apache.http.message.BasicStatusLine;
2931
import org.easymock.EasyMock;
3032
import org.elasticsearch.rest.RestStatus;
3133
import org.junit.Test;
3234

35+
import java.nio.charset.StandardCharsets;
3336
import java.util.HashMap;
3437
import java.util.Map;
3538

@@ -79,6 +82,49 @@ public void testCustomWebhookMessage() throws Exception {
7982
assertEquals(expectedCustomWebhookResponse.getStatusCode(), actualCustomResponse.getStatusCode());
8083
}
8184

85+
@Test
86+
public void testCustomWebhookMessageWithHeaders() throws Exception {
87+
88+
CloseableHttpClient mockHttpClient = EasyMock.createMock(CloseableHttpClient.class);
89+
90+
DestinationHttpResponse expectedCustomWebhookResponse = new DestinationHttpResponse.Builder()
91+
.withResponseContent("<response><status>200</status></response>")
92+
.withStatusCode(RestStatus.OK.getStatus()).build();
93+
CloseableHttpResponse httpResponse = EasyMock.createMock(CloseableHttpResponse.class);
94+
EasyMock.expect(mockHttpClient.execute(EasyMock.anyObject(HttpPost.class))).andReturn(httpResponse);
95+
96+
BasicStatusLine mockStatusLine = EasyMock.createMock(BasicStatusLine.class);
97+
98+
EasyMock.expect(httpResponse.getStatusLine()).andReturn(mockStatusLine);
99+
EasyMock.expect(httpResponse.getEntity()).andReturn(
100+
new StringEntity("<response><status>200</status></response>",
101+
ContentType.create("application/xml", StandardCharsets.UTF_8))).anyTimes();
102+
EasyMock.expect(mockStatusLine.getStatusCode()).andReturn(RestStatus.OK.getStatus());
103+
EasyMock.replay(mockHttpClient);
104+
EasyMock.replay(httpResponse);
105+
EasyMock.replay(mockStatusLine);
106+
107+
DestinationHttpClient httpClient = new DestinationHttpClient();
108+
httpClient.setHttpClient(mockHttpClient);
109+
CustomWebhookDestinationFactory customDestinationFactory = new CustomWebhookDestinationFactory();
110+
customDestinationFactory.setClient(httpClient);
111+
112+
DestinationFactoryProvider.setFactory(DestinationType.CUSTOMWEBHOOK, customDestinationFactory);
113+
114+
Map<String, String> headerParams = new HashMap<String, String>();
115+
headerParams .put("Content-Type", "application/xml");
116+
117+
String message = "<message>Hello</message>";
118+
BaseMessage bm = new CustomWebhookMessage.Builder("abc").withHost("hooks.chime.aws").
119+
withPath("incomingwebhooks/383c0e2b-d028-44f4-8d38-696754bc4574").
120+
withMessage(message).
121+
withHeaderParams(headerParams ).build();
122+
DestinationHttpResponse actualCustomResponse = (DestinationHttpResponse) Notification.publish(bm);
123+
124+
assertEquals(expectedCustomWebhookResponse.getResponseContent(), actualCustomResponse.getResponseContent());
125+
assertEquals(expectedCustomWebhookResponse.getStatusCode(), actualCustomResponse.getStatusCode());
126+
}
127+
82128
@Test(expected = IllegalArgumentException.class)
83129
public void testUrlMissingMessage() {
84130
try {

0 commit comments

Comments
 (0)