Skip to content
22 changes: 12 additions & 10 deletions apm-agent-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,6 @@
</build>

<dependencies>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>${version.okhttp}</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>logging-interceptor</artifactId>
<version>${version.okhttp}</version>
</dependency>
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
Expand Down Expand Up @@ -102,6 +92,18 @@
<version>${version.byte-buddy}</version>
</dependency>

<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>${version.okhttp}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>logging-interceptor</artifactId>
<version>${version.okhttp}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.undertow</groupId>
<artifactId>undertow-core</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,50 +19,70 @@
*/
package co.elastic.apm.report;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSocketFactory;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;

// TODO use UrlConnection and remove OkHttp dependency
class ApmServerHealthChecker implements Runnable {
private static final Logger logger = LoggerFactory.getLogger(ApmServerHealthChecker.class);
private final OkHttpClient httpClient;

private final ReporterConfiguration reporterConfiguration;

ApmServerHealthChecker(OkHttpClient httpClient, ReporterConfiguration reporterConfiguration) {
this.httpClient = httpClient;
ApmServerHealthChecker(ReporterConfiguration reporterConfiguration) {
this.reporterConfiguration = reporterConfiguration;
}

@Override
public void run() {
boolean success;
String message = null;
HttpURLConnection connection = null;
try {
final Response response = httpClient.newCall(new Request.Builder()
.url(reporterConfiguration.getServerUrls().get(0).toString())
.build())
.execute();
final int status = response.code();
URL url = new URL(reporterConfiguration.getServerUrls().get(0).toString() + "/healthcheck");
if (logger.isDebugEnabled()) {
logger.debug("Starting healthcheck to {}", url);
}
connection = (HttpURLConnection) url.openConnection();
if (!reporterConfiguration.isVerifyServerCert()) {
if (connection instanceof HttpsURLConnection) {
trustAll((HttpsURLConnection) connection);
}
}
if (reporterConfiguration.getSecretToken() != null) {
connection.setRequestProperty("Authorization", "Bearer " + reporterConfiguration.getSecretToken());
}
connection.setConnectTimeout((int) reporterConfiguration.getServerTimeout().getMillis());
connection.setReadTimeout((int) reporterConfiguration.getServerTimeout().getMillis());
connection.connect();

final int status = connection.getResponseCode();

success = status < 300;

if (!success) {
if (status == 404) {
message = "It seems like you are using a version of the APM Server which is not compatible with this agent. " +
"Please use APM Server 6.5.0 or newer.";
} else {
message = Integer.toString(status);
}
} else if (response.body() != null) {
} else {
// prints out the version info of the APM Server
message = response.body().string();
message = HttpUtils.getBody(connection);
}
} catch (IOException e) {
message = e.getMessage();
success = false;
} finally {
if (connection != null) {
connection.disconnect();
connection = null;
}
}

if (success) {
Expand All @@ -71,4 +91,13 @@ public void run() {
logger.warn("Elastic APM server is not available ({})", message);
}
}

private void trustAll(HttpsURLConnection connection) {
final SSLSocketFactory sf = SslUtils.getTrustAllSocketFactory();
if (sf != null) {
// using the same instances is important for TCP connection reuse
connection.setHostnameVerifier(SslUtils.getTrustAllHostnameVerifyer());
connection.setSSLSocketFactory(sf);
}
}
}
69 changes: 69 additions & 0 deletions apm-agent-core/src/main/java/co/elastic/apm/report/HttpUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*-
* #%L
* Elastic APM Java agent
* %%
* Copyright (C) 2018 Elastic and contributors
* %%
* Licensed 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.
* #L%
*/
package co.elastic.apm.report;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;

public class HttpUtils {

private static final Logger logger = LoggerFactory.getLogger(HttpUtils.class);

private HttpUtils() {

}

public static String getBody(HttpURLConnection connection) {
String body;
try {
if (connection == null || connection.getInputStream() == null)
return null;
body = readInputStream(connection.getInputStream());
return body;
} catch (final IOException e) {
logger.error("Reading inputStream: {}", e.getMessage());
try {
body = readInputStream(connection.getErrorStream());
return body;
} catch (IOException e1) {
logger.error("Reading errorStream: {}", e1.getMessage());
}
}
return null;
}

private static String readInputStream(final InputStream inputStream) throws IOException {
final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
final StringBuilder bodyString = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
bodyString.append(line);
}
bufferedReader.close();
return bodyString.toString();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -28,23 +28,15 @@
import co.elastic.apm.report.processor.ProcessorEventHandler;
import co.elastic.apm.report.serialize.DslJsonSerializer;
import co.elastic.apm.util.VersionUtils;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.stagemonitor.configuration.ConfigurationRegistry;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.net.ssl.SSLSocketFactory;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;

public class ReporterFactory {

Expand All @@ -54,7 +46,6 @@ public class ReporterFactory {
public Reporter createReporter(ConfigurationRegistry configurationRegistry, @Nullable String frameworkName,
@Nullable String frameworkVersion) {
final ReporterConfiguration reporterConfiguration = configurationRegistry.getConfig(ReporterConfiguration.class);
final OkHttpClient httpClient = getOkHttpClient(reporterConfiguration);
ExecutorService healthCheckExecutorService = Executors.newFixedThreadPool(1, new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Expand All @@ -64,7 +55,7 @@ public Thread newThread(Runnable r) {
return thread;
}
});
healthCheckExecutorService.submit(new ApmServerHealthChecker(httpClient, reporterConfiguration));
healthCheckExecutorService.submit(new ApmServerHealthChecker(reporterConfiguration));
healthCheckExecutorService.shutdown();
final ReportingEventHandler reportingEventHandler = getReportingEventHandler(configurationRegistry, frameworkName,
frameworkVersion, reporterConfiguration);
Expand All @@ -87,45 +78,11 @@ private ReportingEventHandler getReportingEventHandler(ConfigurationRegistry con
processorEventHandler, payloadSerializer);
}

@Nonnull
OkHttpClient getOkHttpClient(ReporterConfiguration reporterConfiguration) {
final OkHttpClient.Builder builder = new OkHttpClient.Builder()
.connectTimeout(reporterConfiguration.getServerTimeout().getMillis(), TimeUnit.MILLISECONDS);
if (!reporterConfiguration.isVerifyServerCert()) {
disableCertificateValidation(builder);
}
if (logger.isTraceEnabled()) {
final HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.HEADERS);
builder.addInterceptor(loggingInterceptor);
}
builder.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
Request requestWithUserAgent = originalRequest.newBuilder()
.header("User-Agent", userAgent)
.build();
return chain.proceed(chain.request());
}
});
return builder.build();
}

private String getUserAgent() {
String agentVersion = VersionUtils.getAgentVersion();
if (agentVersion != null) {
return "apm-agent-java " + agentVersion;
}
return "apm-agent-java";
}

private void disableCertificateValidation(OkHttpClient.Builder builder) {
final SSLSocketFactory sf = SslUtils.getTrustAllSocketFactory();
if (sf != null) {
builder
.sslSocketFactory(sf, SslUtils.getTrustAllTrustManager())
.hostnameVerifier(SslUtils.getTrustAllHostnameVerifyer());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ final void initServer() throws Exception {
.build();
}


protected Response get(String path) throws IOException {
return httpClient.newCall(new okhttp3.Request.Builder().url("http://localhost:" + getPort() + path).build()).execute();
}
Expand Down
12 changes: 12 additions & 0 deletions apm-agent-plugins/apm-servlet-plugin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,18 @@
<version>${version.spring}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>${version.okhttp}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>logging-interceptor</artifactId>
<version>${version.okhttp}</version>
<scope>test</scope>
</dependency>
</dependencies>


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ private void testInstrumentation(ElasticApmInstrumentation instrumentation, int
final Response response = get(path);
assertThat(response.code()).isEqualTo(200);
assertThat(response.body().string()).isEqualTo("Hello World!");

if (expectedTransactions > 0) {
reporter.getFirstTransaction(500);
}
Expand Down
8 changes: 0 additions & 8 deletions elastic-apm-agent/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,6 @@
<pattern>com.lmax</pattern>
<shadedPattern>co.elastic.apm.shaded.lmax</shadedPattern>
</relocation>
<relocation>
<pattern>okhttp</pattern>
<shadedPattern>co.elastic.apm.shaded.okhttp</shadedPattern>
</relocation>
<relocation>
<pattern>okio</pattern>
<shadedPattern>co.elastic.apm.shaded.okio</shadedPattern>
</relocation>
<relocation>
<pattern>org.slf4j</pattern>
<shadedPattern>co.elastic.apm.shaded.slf4j</shadedPattern>
Expand Down