Skip to content

Commit 21cbc72

Browse files
committed
Plugin customised to support AWS ES Authentication and Authorisation
1 parent 469bff2 commit 21cbc72

File tree

3 files changed

+77
-27
lines changed

3 files changed

+77
-27
lines changed

pom.xml

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,12 @@
99
<name>jmeter.backendlistener.elasticsearch</name>
1010
<description>JMeter ElasticSearch Backend Listener is a JMeter plugin enabling you to send test results to an ElasticSearch engine. It is meant as an alternative live-monitoring tool to the built-in "InfluxDB" backend listener of JMeter.</description>
1111
<url>https://github.com/delirius325/jmeter-elasticsearch-backend-listener</url>
12-
12+
<repositories>
13+
<repository>
14+
<id>jitpack.io</id>
15+
<url>https://jitpack.io</url>
16+
</repository>
17+
</repositories>
1318
<licenses>
1419
<license>
1520
<name>The MIT License</name>
@@ -121,6 +126,26 @@
121126
<artifactId>jackson-databind</artifactId>
122127
<version>2.8.11.3</version>
123128
</dependency>
129+
<dependency>
130+
<groupId>com.amazonaws</groupId>
131+
<artifactId>aws-java-sdk-core</artifactId>
132+
<version>1.11.495</version>
133+
</dependency>
134+
<dependency>
135+
<groupId>com.amazonaws</groupId>
136+
<artifactId>aws-java-sdk-secretsmanager</artifactId>
137+
<version>1.11.495</version>
138+
</dependency>
139+
<dependency>
140+
<groupId>vc.inreach.aws</groupId>
141+
<artifactId>aws-signing-request-interceptor</artifactId>
142+
<version>0.0.22</version>
143+
</dependency>
144+
<dependency>
145+
<groupId>com.github.awslabs</groupId>
146+
<artifactId>aws-request-signing-apache-interceptor</artifactId>
147+
<version>b3772780da</version>
148+
</dependency>
124149
</dependencies>
125150
<distributionManagement>
126151
<snapshotRepository>

src/main/java/io/github/delirius325/jmeter/backendlistener/elasticsearch/ElasticSearchMetricSender.java

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,15 @@ public class ElasticSearchMetricSender {
2929
private List<String> metricList;
3030
private String authUser;
3131
private String authPwd;
32+
private String awsendpoint;
3233

33-
public ElasticSearchMetricSender(RestClient cli, String index, String user, String pwd) {
34+
public ElasticSearchMetricSender(RestClient cli, String index, String user, String pwd, String endpoint) {
3435
this.client = cli;
3536
this.esIndex = index;
3637
this.metricList = new LinkedList<String>();
3738
this.authUser = user.trim();
3839
this.authPwd = pwd.trim();
40+
this.awsendpoint = endpoint;
3941
}
4042

4143
/**
@@ -89,22 +91,24 @@ public void sendRequest() {
8991

9092
request.setEntity(new NStringEntity(bulkRequestBody.toString(), ContentType.APPLICATION_JSON));
9193

92-
try {
93-
if(!this.authUser.equals("") && !this.authPwd.equals("")) {
94-
String encodedCredentials = Base64.getEncoder().encodeToString((this.authUser + ":" + this.authPwd).getBytes());
95-
RequestOptions.Builder options = request.getOptions().toBuilder();
96-
options.addHeader("Authorization", "Basic " + encodedCredentials);
97-
request.setOptions(options);
98-
}
94+
try {
9995

100-
Response response = this.client.performRequest(request);
96+
if(this.awsendpoint.equals("") && !this.authPwd.equals("") ) {
97+
String encodedCredentials = Base64.getEncoder().encodeToString((this.authUser + ":" + this.authPwd).getBytes());
98+
RequestOptions.Builder options = request.getOptions().toBuilder();
99+
options.addHeader("Authorization", "Basic " + encodedCredentials);
100+
request.setOptions(options);
101+
}
102+
103+
Response response = this.client.performRequest(request);
101104

102105
if(response.getStatusLine().getStatusCode() != HttpStatus.SC_OK && logger.isErrorEnabled()) {
103106
logger.error("ElasticSearch Backend Listener failed to write results for index {}", this.esIndex);
104-
}
107+
}
105108
} catch (Exception e) {
106-
if(logger.isErrorEnabled()) {
107-
logger.error("ElasticSearch Backend Listener was unable to perform request to the ElasticSearch engine. Request reached timeout.");
109+
if(logger.isErrorEnabled()) {
110+
logger.error("Exception" + e);
111+
logger.error("ElasticSearch Backend Listener was unable to perform request to the ElasticSearch engine. Request reached timeout.");
108112
}
109113
}
110114
}

src/main/java/io/github/delirius325/jmeter/backendlistener/elasticsearch/ElasticsearchBackendClient.java

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.github.delirius325.jmeter.backendlistener.elasticsearch;
22

3+
34
import com.google.gson.Gson;
45
import org.apache.http.HttpHost;
56
import org.apache.jmeter.config.Arguments;
@@ -11,6 +12,11 @@
1112
import org.elasticsearch.client.RestClient;
1213
import org.slf4j.Logger;
1314
import org.slf4j.LoggerFactory;
15+
import com.amazonaws.auth.AWSCredentialsProvider;
16+
import com.amazonaws.auth.AWS4Signer;
17+
import com.amazonaws.http.AWSRequestSigningApacheInterceptor;
18+
import com.amazonaws.auth.DefaultAWSCredentialsProviderChain;
19+
import org.apache.http.HttpRequestInterceptor;
1420

1521
import java.util.*;
1622

@@ -29,8 +35,13 @@ public class ElasticsearchBackendClient extends AbstractBackendListenerClient {
2935
private static final String ES_AUTH_PWD = "es.xpack.password";
3036
private static final String ES_PARSE_REQ_HEADERS = "es.parse.all.req.headers";
3137
private static final String ES_PARSE_RES_HEADERS = "es.parse.all.res.headers";
38+
private static final String ES_AWS_ENDPOINT = "es.aws.endpoint";
39+
private static final String ES_AWS_REGION = "es.aws.region";
3240
private static final long DEFAULT_TIMEOUT_MS = 200L;
41+
private static final String SERVICE_NAME = "es";
42+
private static RestClient client;
3343
private static final Logger logger = LoggerFactory.getLogger(ElasticsearchBackendClient.class);
44+
private static final AWSCredentialsProvider credentialsProvider = new DefaultAWSCredentialsProviderChain();
3445

3546
private ElasticSearchMetricSender sender;
3647
private Set<String> modes;
@@ -55,6 +66,8 @@ public Arguments getDefaultParameters() {
5566
parameters.addArgument(ES_AUTH_PWD, "");
5667
parameters.addArgument(ES_PARSE_REQ_HEADERS, "false");
5768
parameters.addArgument(ES_PARSE_RES_HEADERS, "false");
69+
parameters.addArgument(ES_AWS_ENDPOINT, "");
70+
parameters.addArgument(ES_AWS_REGION, "");
5871
return parameters;
5972
}
6073

@@ -66,19 +79,28 @@ public void setupTest(BackendListenerContext context) throws Exception {
6679
this.bulkSize = Integer.parseInt(context.getParameter(ES_BULK_SIZE));
6780
this.timeoutMs = JMeterUtils.getPropDefault(ES_TIMEOUT_MS, DEFAULT_TIMEOUT_MS);
6881
this.buildNumber = (JMeterUtils.getProperty(ElasticsearchBackendClient.BUILD_NUMBER) != null && !JMeterUtils.getProperty(ElasticsearchBackendClient.BUILD_NUMBER).trim().equals("")) ? Integer.parseInt(JMeterUtils.getProperty(ElasticsearchBackendClient.BUILD_NUMBER)) : 0;
69-
RestClient client = RestClient.builder(new HttpHost(context.getParameter(ES_HOST), Integer.parseInt(context.getParameter(ES_PORT)), context.getParameter(ES_SCHEME)))
70-
.setRequestConfigCallback(requestConfigBuilder -> requestConfigBuilder.setConnectTimeout(5000)
71-
.setSocketTimeout((int) timeoutMs))
72-
.setFailureListener(new RestClient.FailureListener() {
73-
@Override
74-
public void onFailure(Node node) {
75-
throw new IllegalStateException();
76-
}
77-
})
78-
.setMaxRetryTimeoutMillis(60000)
79-
.build();
80-
81-
this.sender = new ElasticSearchMetricSender(client, context.getParameter(ES_INDEX).toLowerCase() ,context.getParameter(ES_AUTH_USER), context.getParameter(ES_AUTH_PWD));
82+
83+
if (context.getParameter(ES_AWS_ENDPOINT).equalsIgnoreCase("")) {
84+
client = RestClient.builder(new HttpHost(context.getParameter(ES_HOST), Integer.parseInt(context.getParameter(ES_PORT)), context.getParameter(ES_SCHEME)))
85+
.setRequestConfigCallback(requestConfigBuilder -> requestConfigBuilder.setConnectTimeout(5000)
86+
.setSocketTimeout((int) timeoutMs))
87+
.setFailureListener(new RestClient.FailureListener() {
88+
@Override
89+
public void onFailure(Node node) {
90+
throw new IllegalStateException();
91+
}
92+
})
93+
.setMaxRetryTimeoutMillis(60000)
94+
.build();
95+
} else {
96+
97+
AWS4Signer signer = new AWS4Signer();
98+
signer.setServiceName(SERVICE_NAME);
99+
signer.setRegionName(context.getParameter(ES_AWS_REGION));
100+
HttpRequestInterceptor interceptor = new AWSRequestSigningApacheInterceptor(SERVICE_NAME, signer, credentialsProvider);
101+
client = RestClient.builder(HttpHost.create(context.getParameter(ES_AWS_ENDPOINT))).setHttpClientConfigCallback(hacb -> hacb.addInterceptorLast(interceptor)).build();
102+
}
103+
this.sender = new ElasticSearchMetricSender(client, context.getParameter(ES_INDEX).toLowerCase(),context.getParameter(ES_AUTH_USER), context.getParameter(ES_AUTH_PWD), context.getParameter(ES_AWS_ENDPOINT));
82104
this.sender.createIndex();
83105

84106
checkTestMode(context.getParameter(ES_TEST_MODE));
@@ -90,7 +112,6 @@ public void onFailure(Node node) {
90112
logger.info("Added filter: " + filter.toLowerCase().trim());
91113
}
92114
}
93-
94115
super.setupTest(context);
95116
} catch (Exception e) {
96117
throw new IllegalStateException("Unable to connect to the ElasticSearch engine", e);

0 commit comments

Comments
 (0)