This is an automated email from the ASF dual-hosted git repository.
pmouawad pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jmeter.git
The following commit(s) were added to refs/heads/master by this push:
new bdcc044 Add support for InfluxDB 2 (#487)
bdcc044 is described below
commit bdcc0442398682dc27a98af579904de10b5bd361
Author: Jakub Bednář <[email protected]>
AuthorDate: Tue Sep 3 15:39:50 2019 +0200
Add support for InfluxDB 2 (#487)
* Added support for InfluxDB 2 auth token
* Start HttpServer on free port
* The token has to be a non blank string, Authorization header name and
value are constant
this fixes https://bz.apache.org/bugzilla/show_bug.cgi?id=63720
Contributed by Jakub Bednář
---
.../backend/influxdb/HttpMetricsSender.java | 23 +++-
.../influxdb/InfluxdbBackendListenerClient.java | 3 +-
.../backend/influxdb/InfluxdbMetricsSender.java | 3 +-
.../backend/influxdb/UdpMetricsSender.java | 2 +-
.../backend/influxdb/HttpMetricsSenderTest.java | 144 +++++++++++++++++++++
xdocs/usermanual/component_reference.xml | 1 +
6 files changed, 168 insertions(+), 8 deletions(-)
diff --git
a/src/components/src/main/java/org/apache/jmeter/visualizers/backend/influxdb/HttpMetricsSender.java
b/src/components/src/main/java/org/apache/jmeter/visualizers/backend/influxdb/HttpMetricsSender.java
index 272bc5b..5f13876 100644
---
a/src/components/src/main/java/org/apache/jmeter/visualizers/backend/influxdb/HttpMetricsSender.java
+++
b/src/components/src/main/java/org/apache/jmeter/visualizers/backend/influxdb/HttpMetricsSender.java
@@ -29,6 +29,7 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
@@ -58,6 +59,9 @@ import org.slf4j.LoggerFactory;
class HttpMetricsSender extends AbstractInfluxdbMetricsSender {
private static final Logger log =
LoggerFactory.getLogger(HttpMetricsSender.class);
+ private static final String AUTHORIZATION_HEADER_NAME = "Authorization";
+ private static final String AUTHORIZATION_HEADER_VALUE = "Token ";
+
private final Object lock = new Object();
private List<MetricTuple> metrics = new ArrayList<>();
@@ -68,6 +72,8 @@ class HttpMetricsSender extends AbstractInfluxdbMetricsSender
{
private URL url;
+ private String token;
+
private Future<HttpResponse> lastRequest;
HttpMetricsSender() {
@@ -81,10 +87,12 @@ class HttpMetricsSender extends
AbstractInfluxdbMetricsSender {
*
* @param influxdbUrl
* example : http://localhost:8086/write?db=myd&rp=one_week
- * @see
org.apache.jmeter.visualizers.backend.influxdb.InfluxdbMetricsSender#setup(java.lang.String)
+ * @param influxDBToken
+ * example: my-token
+ * @see InfluxdbMetricsSender#setup(String, String)
*/
@Override
- public void setup(String influxdbUrl) throws Exception {
+ public void setup(String influxdbUrl, String influxDBToken) throws
Exception {
// Create I/O reactor configuration
IOReactorConfig ioReactorConfig = IOReactorConfig
.custom()
@@ -108,16 +116,18 @@ class HttpMetricsSender extends
AbstractInfluxdbMetricsSender {
.disableConnectionState()
.build();
url = new URL(influxdbUrl);
- httpRequest = createRequest(url);
+ token = influxDBToken;
+ httpRequest = createRequest(url, token);
httpClient.start();
}
/**
* @param url {@link URL} Influxdb Url
+ * @param token Influxdb 2.0 authorization token
* @return {@link HttpPost}
* @throws URISyntaxException
*/
- private HttpPost createRequest(URL url) throws URISyntaxException {
+ private HttpPost createRequest(URL url, String token) throws
URISyntaxException {
RequestConfig defaultRequestConfig = RequestConfig.custom()
.setConnectTimeout(JMeterUtils.getPropDefault("backend_influxdb.connection_timeout",
1000))
.setSocketTimeout(JMeterUtils.getPropDefault("backend_influxdb.socket_timeout",
3000))
@@ -126,6 +136,9 @@ class HttpMetricsSender extends
AbstractInfluxdbMetricsSender {
HttpPost currentHttpRequest = new HttpPost(url.toURI());
currentHttpRequest.setConfig(defaultRequestConfig);
+ if (StringUtils.isNotBlank(token)) {
+ currentHttpRequest.setHeader(AUTHORIZATION_HEADER_NAME,
AUTHORIZATION_HEADER_VALUE + token);
+ }
log.debug("Created InfluxDBMetricsSender with url: {}", url);
return currentHttpRequest;
}
@@ -154,7 +167,7 @@ class HttpMetricsSender extends
AbstractInfluxdbMetricsSender {
if (!copyMetrics.isEmpty()) {
try {
if(httpRequest == null) {
- httpRequest = createRequest(url);
+ httpRequest = createRequest(url, token);
}
StringBuilder sb = new StringBuilder(copyMetrics.size()*35);
for (MetricTuple metric : copyMetrics) {
diff --git
a/src/components/src/main/java/org/apache/jmeter/visualizers/backend/influxdb/InfluxdbBackendListenerClient.java
b/src/components/src/main/java/org/apache/jmeter/visualizers/backend/influxdb/InfluxdbBackendListenerClient.java
index 33a320c..212fe1b 100644
---
a/src/components/src/main/java/org/apache/jmeter/visualizers/backend/influxdb/InfluxdbBackendListenerClient.java
+++
b/src/components/src/main/java/org/apache/jmeter/visualizers/backend/influxdb/InfluxdbBackendListenerClient.java
@@ -316,6 +316,7 @@ public class InfluxdbBackendListenerClient extends
AbstractBackendListenerClient
public void setupTest(BackendListenerContext context) throws Exception {
String influxdbMetricsSender =
context.getParameter("influxdbMetricsSender");
String influxdbUrl = context.getParameter("influxdbUrl");
+ String influxdbToken = context.getParameter("influxdbToken");
summaryOnly = context.getBooleanParameter("summaryOnly", false);
samplersRegex = context.getParameter("samplersRegex", "");
application =
AbstractInfluxdbMetricsSender.tagToStringValue(context.getParameter("application",
""));
@@ -366,7 +367,7 @@ public class InfluxdbBackendListenerClient extends
AbstractBackendListenerClient
Class<?> clazz = Class.forName(influxdbMetricsSender);
this.influxdbMetricsManager = (InfluxdbMetricsSender)
clazz.getDeclaredConstructor().newInstance();
- influxdbMetricsManager.setup(influxdbUrl);
+ influxdbMetricsManager.setup(influxdbUrl, influxdbToken);
samplersToFilter = Pattern.compile(samplersRegex);
addAnnotation(true);
diff --git
a/src/components/src/main/java/org/apache/jmeter/visualizers/backend/influxdb/InfluxdbMetricsSender.java
b/src/components/src/main/java/org/apache/jmeter/visualizers/backend/influxdb/InfluxdbMetricsSender.java
index 99261c1..f815a7a 100644
---
a/src/components/src/main/java/org/apache/jmeter/visualizers/backend/influxdb/InfluxdbMetricsSender.java
+++
b/src/components/src/main/java/org/apache/jmeter/visualizers/backend/influxdb/InfluxdbMetricsSender.java
@@ -57,9 +57,10 @@ interface InfluxdbMetricsSender {
/**
* Setup sender using influxDBUrl
* @param influxDBUrl url pointing to influxdb
+ * @param influxDBToken authorization token to influxdb 2.0
* @throws Exception when setup fails
*/
- public void setup(String influxDBUrl) throws Exception; // NOSONAR
+ public void setup(String influxDBUrl, String influxDBToken) throws
Exception; // NOSONAR
/**
* Destroy sender
diff --git
a/src/components/src/main/java/org/apache/jmeter/visualizers/backend/influxdb/UdpMetricsSender.java
b/src/components/src/main/java/org/apache/jmeter/visualizers/backend/influxdb/UdpMetricsSender.java
index e6e55c1..f3a8e85 100644
---
a/src/components/src/main/java/org/apache/jmeter/visualizers/backend/influxdb/UdpMetricsSender.java
+++
b/src/components/src/main/java/org/apache/jmeter/visualizers/backend/influxdb/UdpMetricsSender.java
@@ -56,7 +56,7 @@ class UdpMetricsSender extends AbstractInfluxdbMetricsSender {
}
@Override
- public void setup(String influxdbUrl) throws Exception {
+ public void setup(String influxdbUrl, String influxDBToken) throws
Exception {
try {
log.debug("Setting up with url:{}", influxdbUrl);
String[] urlComponents = influxdbUrl.split(":");
diff --git
a/src/components/src/test/java/org/apache/jmeter/visualizers/backend/influxdb/HttpMetricsSenderTest.java
b/src/components/src/test/java/org/apache/jmeter/visualizers/backend/influxdb/HttpMetricsSenderTest.java
new file mode 100644
index 0000000..7a1b4f0
--- /dev/null
+++
b/src/components/src/test/java/org/apache/jmeter/visualizers/backend/influxdb/HttpMetricsSenderTest.java
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.jmeter.visualizers.backend.influxdb;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import java.io.IOException;
+import java.util.Objects;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.IntStream;
+
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpStatus;
+import org.apache.http.impl.bootstrap.HttpServer;
+import org.apache.http.impl.bootstrap.ServerBootstrap;
+import org.apache.http.protocol.HttpRequestHandler;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class HttpMetricsSenderTest {
+
+ private HttpServer server;
+ private HttpRequest request;
+
+ @Before
+ public void startServer() {
+
+ HttpRequestHandler requestHandler = (request, response, context) -> {
+ HttpMetricsSenderTest.this.request = request;
+ response.setStatusCode(HttpStatus.SC_NO_CONTENT);
+ };
+
+ // Start HttpServer on free port
+ server = IntStream
+ .range(8183, 8283)
+ .mapToObj(port -> {
+ HttpServer httpServer = ServerBootstrap.bootstrap()
+ .setListenerPort(8183)
+ .registerHandler("*", requestHandler)
+ .create();
+ try {
+ httpServer.start();
+ return httpServer;
+ } catch (IOException e) {
+ return null;
+ }
+ })
+ .filter(Objects::nonNull)
+ .findFirst()
+ .orElseThrow(() -> new AssertionError("Cannot start
HttpServer"));
+ }
+
+ @After
+ public void stopServer() {
+ server.shutdown(1, TimeUnit.SECONDS);
+ }
+
+ @Test
+ public void checkTokenDoesNotPresentInHeader() throws Exception {
+ String influxdbUrl = String.format("http://localhost:%s/api/v2/write",
server.getLocalPort());
+ HttpMetricsSender metricsSender = new HttpMetricsSender();
+ metricsSender.setup(influxdbUrl, null);
+ metricsSender.addMetric("measurement", "location=west", "size=10");
+ metricsSender.writeAndSendMetrics();
+
+ do {
+ Thread.sleep(100);
+ } while (request == null);
+
+ assertNull(
+ "The authorization header shouldn't be defined.",
+ request.getFirstHeader("Authorization"));
+ }
+
+ @Test
+ public void checkEmptyTokenDoesNotPresentInHeader() throws Exception {
+ String influxdbUrl = String.format("http://localhost:%s/api/v2/write",
server.getLocalPort());
+ HttpMetricsSender metricsSender = new HttpMetricsSender();
+ metricsSender.setup(influxdbUrl, "");
+ metricsSender.addMetric("measurement", "location=west", "size=10");
+ metricsSender.writeAndSendMetrics();
+
+ do {
+ Thread.sleep(100);
+ } while (request == null);
+
+ assertNull(
+ "The authorization header shouldn't be defined.",
+ request.getFirstHeader("Authorization"));
+ }
+
+ @Test
+ public void checkEmptyOnlyWhitespaceTokenDoesNotPresentInHeader() throws
Exception {
+ String influxdbUrl = String.format("http://localhost:%s/api/v2/write",
server.getLocalPort());
+ HttpMetricsSender metricsSender = new HttpMetricsSender();
+ metricsSender.setup(influxdbUrl, " ");
+ metricsSender.addMetric("measurement", "location=west", "size=10");
+ metricsSender.writeAndSendMetrics();
+
+ do {
+ Thread.sleep(100);
+ } while (request == null);
+
+ assertNull(
+ "The authorization header shouldn't be defined.",
+ request.getFirstHeader("Authorization"));
+ }
+
+ @Test
+ public void checkTokenPresentInHeader() throws Exception {
+ String influxdbUrl = String.format("http://localhost:%s/api/v2/write",
server.getLocalPort());
+ HttpMetricsSender metricsSender = new HttpMetricsSender();
+ metricsSender.setup(influxdbUrl, "my-token");
+ metricsSender.addMetric("measurement", "location=west", "size=10");
+ metricsSender.writeAndSendMetrics();
+
+ do {
+ Thread.sleep(100);
+ } while (request == null);
+
+ assertEquals(
+ "The authorization header should be: 'Token my-token'",
+ request.getFirstHeader("Authorization").getValue(),
+ "Token my-token");
+ }
+}
diff --git a/xdocs/usermanual/component_reference.xml
b/xdocs/usermanual/component_reference.xml
index ac0c278..6e80b50 100644
--- a/xdocs/usermanual/component_reference.xml
+++ b/xdocs/usermanual/component_reference.xml
@@ -3395,6 +3395,7 @@ By default, a Graphite implementation is provided.
<properties>
<property name="influxdbMetricsSender"
required="Yes"><code>org.apache.jmeter.visualizers.backend.influxdb.HttpMetricsSender</code></property>
<property name="influxdbUrl" required="Yes">Influx URL (example :
http://influxHost:8086/write?db=jmeter)</property>
+ <property name="influxdbToken" required="No">InfluxDB 2 <a
href="https://v2.docs.influxdata.com/v2.0/security/">authentication token</a>
(example : HE9yIdAPzWJDspH_tCc2UvdKZpX==); since 5.2.</property>
<property name="application" required="Yes">Name of tested
application. This value is stored in the 'events' measurement too as a tag
named 'application' </property>
<property name="measurement" required="Yes">Measurement as per <a
href="https://docs.influxdata.com/influxdb/v1.1/write_protocols/line_protocol_reference/">Influx
Line Protocol Reference</a>. Defaults to "<code>jmeter</code>."</property>
<property name="summaryOnly" required="Yes">Only send a summary with
no detail. Defaults to <code>true</code>.</property>