From 404618d47de4cdcc3feabd088a2846de0cd90dc4 Mon Sep 17 00:00:00 2001 From: Felix Barnsteiner Date: Thu, 12 Apr 2018 10:07:11 +0200 Subject: [PATCH 01/15] Add testcontainers based integration test closes #20 Signed-off-by: Felix Barnsteiner --- .../apm/report/ReporterConfiguration.java | 1 + .../apm/report/ReportingEventHandler.java | 9 +- .../src/test/resources/logback-test.xml | 17 +++ .../apm-servlet-plugin-it/pom.xml | 20 +++ .../simple-webapp-integration-test/pom.xml | 68 +++++++++ .../apm/servlet/ApmTestHelperServlet.java | 49 +++++++ .../src/main/resources/logback.xml | 18 +++ .../src/main/webapp/WEB-INF/web.xml | 23 +++ .../src/main/webapp/index.jsp | 5 + .../AbstractTomcatIntegrationTest.java | 132 ++++++++++++++++++ .../apm/servlet/MockServerContainer.java | 52 +++++++ .../apm/servlet/ServletIntegrationTest.java | 51 +++++++ .../src/test/resources/logback-test.xml | 22 +++ apm-agent-plugins/pom.xml | 1 + docs/configuration.asciidoc | 2 +- pom.xml | 43 ++++-- 16 files changed, 499 insertions(+), 14 deletions(-) create mode 100644 apm-agent-core/src/test/resources/logback-test.xml create mode 100644 apm-agent-plugins/apm-servlet-plugin-it/pom.xml create mode 100644 apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/pom.xml create mode 100644 apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/main/java/co/elastic/apm/servlet/ApmTestHelperServlet.java create mode 100644 apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/main/resources/logback.xml create mode 100644 apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/main/webapp/WEB-INF/web.xml create mode 100644 apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/main/webapp/index.jsp create mode 100644 apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java create mode 100644 apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/MockServerContainer.java create mode 100644 apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/ServletIntegrationTest.java create mode 100644 apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/resources/logback-test.xml diff --git a/apm-agent-core/src/main/java/co/elastic/apm/report/ReporterConfiguration.java b/apm-agent-core/src/main/java/co/elastic/apm/report/ReporterConfiguration.java index e0f8a84c74..7fd0c97a3e 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/report/ReporterConfiguration.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/report/ReporterConfiguration.java @@ -45,6 +45,7 @@ public class ReporterConfiguration extends ConfigurationOptionProvider { .configurationCategory(REPORTER_CATEGORY) .label("The URL for your APM Server") .description("The URL must be fully qualified, including protocol (http or https) and port.") + .dynamic(true) .buildWithDefault(UrlValueConverter.INSTANCE.convert("http://localhost:8200")); private final ConfigurationOption serverTimeout = ConfigurationOption.integerOption() diff --git a/apm-agent-core/src/main/java/co/elastic/apm/report/ReportingEventHandler.java b/apm-agent-core/src/main/java/co/elastic/apm/report/ReportingEventHandler.java index 68c1d3190b..df577de080 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/report/ReportingEventHandler.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/report/ReportingEventHandler.java @@ -7,9 +7,9 @@ * 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. @@ -26,12 +26,15 @@ import co.elastic.apm.impl.payload.SystemInfo; import co.elastic.apm.impl.payload.TransactionPayload; import com.lmax.disruptor.EventHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static co.elastic.apm.report.ReportingEvent.ReportingEventType.ERROR; import static co.elastic.apm.report.ReportingEvent.ReportingEventType.FLUSH; import static co.elastic.apm.report.ReportingEvent.ReportingEventType.TRANSACTION; class ReportingEventHandler implements EventHandler { + private static final Logger logger = LoggerFactory.getLogger(ReportingEventHandler.class); private final TransactionPayload transactionPayload; private final ErrorPayload errorPayload; private final PayloadSender payloadSender; @@ -46,6 +49,7 @@ public ReportingEventHandler(Service service, ProcessInfo process, SystemInfo sy @Override public void onEvent(ReportingEvent event, long sequence, boolean endOfBatch) { + logger.debug("Receiving {} event (sequence {})", event.getType(), sequence); if (event.getType() == FLUSH) { flush(transactionPayload); flush(errorPayload); @@ -63,6 +67,7 @@ public void onEvent(ReportingEvent event, long sequence, boolean endOfBatch) { flush(errorPayload); } } + logger.debug("Finished processing {} event (sequence {})", event.getType(), sequence); event.resetState(); } diff --git a/apm-agent-core/src/test/resources/logback-test.xml b/apm-agent-core/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..1e9838e48e --- /dev/null +++ b/apm-agent-core/src/test/resources/logback-test.xml @@ -0,0 +1,17 @@ + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + diff --git a/apm-agent-plugins/apm-servlet-plugin-it/pom.xml b/apm-agent-plugins/apm-servlet-plugin-it/pom.xml new file mode 100644 index 0000000000..d7495af9f8 --- /dev/null +++ b/apm-agent-plugins/apm-servlet-plugin-it/pom.xml @@ -0,0 +1,20 @@ + + + + apm-agent-plugins + co.elastic.apm + 0.1.2-SNAPSHOT + + 4.0.0 + + apm-servlet-plugin-it + pom + ${project.groupId}:${project.artifactId} + + simple-webapp-integration-test + + + + diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/pom.xml b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/pom.xml new file mode 100644 index 0000000000..5037054ce6 --- /dev/null +++ b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/pom.xml @@ -0,0 +1,68 @@ + + + + + apm-servlet-plugin-it + co.elastic.apm + 0.1.2-SNAPSHOT + + 4.0.0 + + simple-webapp-integration-test + war + + ${project.groupId}:${project.artifactId} + + + ROOT + + + + + ${project.groupId} + apm-servlet-plugin + ${project.version} + + + javax.servlet + javax.servlet-api + 3.0.1 + provided + + + ch.qos.logback + logback-classic + ${version.logback} + + + org.testcontainers + testcontainers + 1.7.0 + test + + + org.mock-server + mockserver-client-java + 5.3.0 + test + + + com.networknt + json-schema-validator + ${version.json-schema-validator} + test + + + + com.fasterxml.jackson.core + jackson-databind + + + + + + diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/main/java/co/elastic/apm/servlet/ApmTestHelperServlet.java b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/main/java/co/elastic/apm/servlet/ApmTestHelperServlet.java new file mode 100644 index 0000000000..7ad890fea0 --- /dev/null +++ b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/main/java/co/elastic/apm/servlet/ApmTestHelperServlet.java @@ -0,0 +1,49 @@ +/*- + * #%L + * Elastic APM Java agent + * %% + * Copyright (C) 2018 the original author or authors + * %% + * 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.servlet; + +import co.elastic.apm.impl.ElasticApmTracer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public class ApmTestHelperServlet extends HttpServlet { + + private static final Logger logger = LoggerFactory.getLogger(ApmTestHelperServlet.class); + private final ElasticApmTracer tracer = ElasticApmTracer.get(); + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException { + try { + switch (req.getPathInfo()) { + case "/flush": + logger.info("Flushing reporter"); + tracer.getReporter().flush().get(); + break; + } + } catch (Exception e) { + throw new ServletException(e); + } + } +} diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/main/resources/logback.xml b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/main/resources/logback.xml new file mode 100644 index 0000000000..1bda817239 --- /dev/null +++ b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/main/resources/logback.xml @@ -0,0 +1,18 @@ + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/main/webapp/WEB-INF/web.xml b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000..5b81707e7f --- /dev/null +++ b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,23 @@ + + + + Simple Web App + + ApmFilter + co.elastic.apm.servlet.ApmFilter + + + ApmFilter + /* + + + ApmTestHelperServlet + co.elastic.apm.servlet.ApmTestHelperServlet + + + ApmTestHelperServlet + /apm/* + + diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/main/webapp/index.jsp b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/main/webapp/index.jsp new file mode 100644 index 0000000000..c38169bb95 --- /dev/null +++ b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/main/webapp/index.jsp @@ -0,0 +1,5 @@ + + +

Hello World!

+ + diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java new file mode 100644 index 0000000000..ad5e5ea47c --- /dev/null +++ b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java @@ -0,0 +1,132 @@ +/*- + * #%L + * Elastic APM Java agent + * %% + * Copyright (C) 2018 the original author or authors + * %% + * 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.servlet; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.networknt.schema.JsonSchema; +import com.networknt.schema.JsonSchemaFactory; +import com.networknt.schema.ValidationMessage; +import okhttp3.HttpUrl; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.mockserver.model.HttpRequest; +import org.mockserver.model.HttpResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.Network; +import org.testcontainers.containers.output.Slf4jLogConsumer; +import org.testcontainers.images.builder.ImageFromDockerfile; + +import java.io.IOException; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockserver.model.HttpRequest.request; + +public class AbstractTomcatIntegrationTest { + + private static final Logger logger = LoggerFactory.getLogger(ServletIntegrationTest.class); + + @ClassRule + public static GenericContainer c = new GenericContainer<>( + new ImageFromDockerfile() + .withDockerfileFromBuilder(builder -> builder + .from("tomcat:9") + .run("rm -rf /usr/local/tomcat/webapps/*") + .copy("ROOT.war", "/usr/local/tomcat/webapps/ROOT.war") + // TODO debugging does not work + // to get the randomized debugger port, evaluate c.getMappedPort(8000) + // then create a remote debug configuration in IntelliJ using this port + // Error running 'Debug': Unable to open debugger port (localhost:33049): java.io.IOException "handshake failed - connection prematurally closed" + .env("JPDA_ADDRESS", "8000") + .env("JPDA_TRANSPORT", "dt_socket") + .env("ELASTIC_APM_SERVER_URL", "http://apm-server:1080") + .env("ELASTIC_APM_SERVICE_NAME", "servlet-test-app") + .env("ELASTIC_APM_IGNORE_URLS", "/apm/*") + .expose(8080, 8000) + .entryPoint("catalina.sh", "jpda", "run") + ) + // TODO chicken egg problem here: tests require the war to be present, which is built via mvn package, but mvn package executes the tests + .withFileFromPath("ROOT.war", Paths.get("target/ROOT.war"))) + .withNetwork(Network.SHARED) + .withExposedPorts(8080, 8000); + @ClassRule + public static MockServerContainer mockServerContainer = new MockServerContainer() + .withNetworkAliases("apm-server") + .withNetwork(Network.SHARED); + protected OkHttpClient httpClient = new OkHttpClient.Builder().build(); + private JsonSchema schema; + + @BeforeClass + public static void beforeClass() { + mockServerContainer.getClient().when(request("/v1/transactions")).respond(HttpResponse.response().withStatusCode(200)); + mockServerContainer.getClient().when(request("/v1/errors")).respond(HttpResponse.response().withStatusCode(200)); + c.followOutput(new Slf4jLogConsumer(logger)); + } + + @Before + public void setUp() { + schema = JsonSchemaFactory.getInstance().getSchema(getClass().getResourceAsStream("/schema/transactions/payload.json")); + } + + protected List getReportedTransactions() throws IOException { + flushReporterQueue(); + final List transactions = new ArrayList<>(); + final ObjectMapper objectMapper = new ObjectMapper(); + for (HttpRequest httpRequest : mockServerContainer.getClient().retrieveRecordedRequests(request("/v1/transactions"))) { + final JsonNode payload = objectMapper.readTree(httpRequest.getBodyAsString()); + validateJsonSchema(payload); + for (JsonNode transaction : payload.get("transactions")) { + transactions.add(transaction); + } + } + return transactions; + } + + private void validateJsonSchema(JsonNode payload) { + Set errors = schema.validate(payload); + assertThat(errors).isEmpty(); + } + + /** + * Makes sure all pending items in the {@link co.elastic.apm.report.Reporter} queue are flushed to the APM server mock + */ + private void flushReporterQueue() throws IOException { + httpClient.newCall(new Request.Builder() + .post(RequestBody.create(null, new byte[0])) + .url(new HttpUrl.Builder() + .scheme("http") + .host(c.getContainerIpAddress()) + .port(c.getFirstMappedPort()) + .encodedPath("/apm/flush") + .build()) + .build()) + .execute(); + } +} diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/MockServerContainer.java b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/MockServerContainer.java new file mode 100644 index 0000000000..02c4a697f2 --- /dev/null +++ b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/MockServerContainer.java @@ -0,0 +1,52 @@ +/*- + * #%L + * Elastic APM Java agent + * %% + * Copyright (C) 2018 the original author or authors + * %% + * 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.servlet; + +import com.github.dockerjava.api.command.InspectContainerResponse; +import org.mockserver.client.server.MockServerClient; +import org.slf4j.LoggerFactory; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.output.Slf4jLogConsumer; + +/** + * Acts as a mock for the APM-server. + * It stores the {@link co.elastic.apm.impl.payload.Payload}s sent to it, + * which can be retrieved via the {@link #client}. + */ +public class MockServerContainer extends GenericContainer { + + private MockServerClient client; + + public MockServerContainer() { + super("jamesdbloom/mockserver:mockserver-5.3.0"); + addExposedPorts(1080); + withLogConsumer(new Slf4jLogConsumer(LoggerFactory.getLogger(getClass()))); + } + + @Override + protected void containerIsStarted(InspectContainerResponse containerInfo) { + super.containerIsStarted(containerInfo); + client = new MockServerClient(getContainerIpAddress(), getFirstMappedPort()); + } + + public MockServerClient getClient() { + return client; + } +} diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/ServletIntegrationTest.java b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/ServletIntegrationTest.java new file mode 100644 index 0000000000..b5974b9877 --- /dev/null +++ b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/ServletIntegrationTest.java @@ -0,0 +1,51 @@ +/*- + * #%L + * Elastic APM Java agent + * %% + * Copyright (C) 2018 the original author or authors + * %% + * 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.servlet; + +import com.fasterxml.jackson.databind.JsonNode; +import okhttp3.Request; +import okhttp3.ResponseBody; +import org.junit.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ServletIntegrationTest extends AbstractTomcatIntegrationTest { + + @Test + public void testTransactionReporting() throws Exception { + final ResponseBody responseBody = httpClient.newCall(new Request.Builder() + .get() + .url("http://" + c.getContainerIpAddress() + ":" + c.getMappedPort(8080) + "/index.jsp") + .build()) + .execute() + .body(); + + assertThat(responseBody).isNotNull(); + assertThat(responseBody.string()).contains("Hello World"); + + final List reportedTransactions = getReportedTransactions(); + assertThat(reportedTransactions.size()).isEqualTo(1); + assertThat(reportedTransactions.iterator().next().get("context").get("request").get("url").get("pathname").textValue()) + .isEqualTo("/index.jsp"); + } + +} diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/resources/logback-test.xml b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..074bd32c18 --- /dev/null +++ b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/resources/logback-test.xml @@ -0,0 +1,22 @@ + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + + + + diff --git a/apm-agent-plugins/pom.xml b/apm-agent-plugins/pom.xml index de49585bfd..bf4a84913e 100644 --- a/apm-agent-plugins/pom.xml +++ b/apm-agent-plugins/pom.xml @@ -9,6 +9,7 @@ pom apm-servlet-plugin + apm-servlet-plugin-it apm-web-plugin apm-jdbc-plugin apm-spring-webmvc-plugin diff --git a/docs/configuration.asciidoc b/docs/configuration.asciidoc index 3bce4b9760..76c1119cc7 100644 --- a/docs/configuration.asciidoc +++ b/docs/configuration.asciidoc @@ -343,7 +343,7 @@ The URL must be fully qualified, including protocol (http or https) and port. [options="header"] |============ | Default | Type | Dynamic -| `pass:[http://localhost:8200]` | URL | false +| `pass:[http://localhost:8200]` | URL | true |============ diff --git a/pom.xml b/pom.xml index 828ca20c60..c2bf95bc70 100644 --- a/pom.xml +++ b/pom.xml @@ -44,8 +44,13 @@ 7 9 false - 2.9.4 - 5.1.0 + + 2.9.2 + 5.1.1 + 4.12 1.7.25 2.2.0 true @@ -60,6 +65,10 @@ 5.0.4.RELEASE 1.4.196 9.4.8.v20171121 + 2.19.1 + 5.1.1 + 1.2.3 + 0.1.19 @@ -301,7 +310,7 @@ maven-surefire-plugin - 2.19.1 + ${version.plugin.surefire} true false @@ -310,12 +319,17 @@ org.junit.platform junit-platform-surefire-provider - 1.0.3 + 1.1.1 + + + org.junit.vintage + junit-vintage-engine + ${version.junit-vintage-engine} org.junit.jupiter junit-jupiter-engine - ${junit.version} + ${version.junit-jupiter} @@ -403,13 +417,20 @@ org.junit.jupiter junit-jupiter-api - ${junit.version} + ${version.junit-jupiter} test org.junit.jupiter junit-jupiter-params - ${junit.version} + ${version.junit-jupiter} + test + + + + junit + junit + ${version.junit.vintage} test @@ -425,15 +446,15 @@ test - org.slf4j - slf4j-simple - ${slf4j.version} + ch.qos.logback + logback-classic + ${version.logback} test com.networknt json-schema-validator - 0.1.16 + ${version.json-schema-validator} test From f4d06015f71b3c8373107c50900b87bf8bd7cc51 Mon Sep 17 00:00:00 2001 From: Felix Barnsteiner Date: Thu, 12 Apr 2018 13:57:19 +0200 Subject: [PATCH 02/15] Apply suggestions Signed-off-by: Felix Barnsteiner --- .../AbstractTomcatIntegrationTest.java | 48 +++++++++---------- .../apm/servlet/ServletIntegrationTest.java | 2 +- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java index ad5e5ea47c..53c026e0c2 100644 --- a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java +++ b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java @@ -30,7 +30,6 @@ import okhttp3.RequestBody; import org.junit.Before; import org.junit.BeforeClass; -import org.junit.ClassRule; import org.mockserver.model.HttpRequest; import org.mockserver.model.HttpResponse; import org.slf4j.Logger; @@ -41,53 +40,54 @@ import org.testcontainers.images.builder.ImageFromDockerfile; import java.io.IOException; -import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; import java.util.Set; +import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; import static org.mockserver.model.HttpRequest.request; -public class AbstractTomcatIntegrationTest { +public abstract class AbstractTomcatIntegrationTest { private static final Logger logger = LoggerFactory.getLogger(ServletIntegrationTest.class); - @ClassRule - public static GenericContainer c = new GenericContainer<>( + protected static GenericContainer tomcatContainer = new GenericContainer<>( new ImageFromDockerfile() .withDockerfileFromBuilder(builder -> builder .from("tomcat:9") .run("rm -rf /usr/local/tomcat/webapps/*") - .copy("ROOT.war", "/usr/local/tomcat/webapps/ROOT.war") - // TODO debugging does not work - // to get the randomized debugger port, evaluate c.getMappedPort(8000) - // then create a remote debug configuration in IntelliJ using this port - // Error running 'Debug': Unable to open debugger port (localhost:33049): java.io.IOException "handshake failed - connection prematurally closed" - .env("JPDA_ADDRESS", "8000") - .env("JPDA_TRANSPORT", "dt_socket") - .env("ELASTIC_APM_SERVER_URL", "http://apm-server:1080") - .env("ELASTIC_APM_SERVICE_NAME", "servlet-test-app") - .env("ELASTIC_APM_IGNORE_URLS", "/apm/*") .expose(8080, 8000) - .entryPoint("catalina.sh", "jpda", "run") - ) - // TODO chicken egg problem here: tests require the war to be present, which is built via mvn package, but mvn package executes the tests - .withFileFromPath("ROOT.war", Paths.get("target/ROOT.war"))) + .entryPoint("catalina.sh", "jpda", "run"))) .withNetwork(Network.SHARED) + // TODO debugging does not work + // to get the randomized debugger port, evaluate tomcatContainer.getMappedPort(8000) + // then create a remote debug configuration in IntelliJ using this port + // Error running 'Debug': Unable to open debugger port (localhost:33049): java.io.IOException "handshake failed - connection prematurally closed".withEnv("JPDA_ADDRESS", "8000") + .withEnv("JPDA_TRANSPORT", "dt_socket") + .withEnv("ELASTIC_APM_SERVER_URL", "http://apm-server:1080") + .withEnv("ELASTIC_APM_SERVICE_NAME", "servlet-test-app") + .withEnv("ELASTIC_APM_IGNORE_URLS", "/apm/*") + .withLogConsumer(new Slf4jLogConsumer(logger)) + // TODO chicken egg problem here: tests require the war to be present, which is built via mvn package, but mvn package executes the tests + .withFileSystemBind("target/ROOT.war", "/usr/local/tomcat/webapps/ROOT.war") .withExposedPorts(8080, 8000); - @ClassRule - public static MockServerContainer mockServerContainer = new MockServerContainer() + protected static MockServerContainer mockServerContainer = new MockServerContainer() .withNetworkAliases("apm-server") .withNetwork(Network.SHARED); + + static { + Stream.of(tomcatContainer, mockServerContainer).parallel().forEach(GenericContainer::start); + } + protected OkHttpClient httpClient = new OkHttpClient.Builder().build(); private JsonSchema schema; + @BeforeClass public static void beforeClass() { mockServerContainer.getClient().when(request("/v1/transactions")).respond(HttpResponse.response().withStatusCode(200)); mockServerContainer.getClient().when(request("/v1/errors")).respond(HttpResponse.response().withStatusCode(200)); - c.followOutput(new Slf4jLogConsumer(logger)); } @Before @@ -122,8 +122,8 @@ private void flushReporterQueue() throws IOException { .post(RequestBody.create(null, new byte[0])) .url(new HttpUrl.Builder() .scheme("http") - .host(c.getContainerIpAddress()) - .port(c.getFirstMappedPort()) + .host(tomcatContainer.getContainerIpAddress()) + .port(tomcatContainer.getFirstMappedPort()) .encodedPath("/apm/flush") .build()) .build()) diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/ServletIntegrationTest.java b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/ServletIntegrationTest.java index b5974b9877..8b35cc410d 100644 --- a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/ServletIntegrationTest.java +++ b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/ServletIntegrationTest.java @@ -34,7 +34,7 @@ public class ServletIntegrationTest extends AbstractTomcatIntegrationTest { public void testTransactionReporting() throws Exception { final ResponseBody responseBody = httpClient.newCall(new Request.Builder() .get() - .url("http://" + c.getContainerIpAddress() + ":" + c.getMappedPort(8080) + "/index.jsp") + .url("http://" + tomcatContainer.getContainerIpAddress() + ":" + tomcatContainer.getMappedPort(8080) + "/index.jsp") .build()) .execute() .body(); From 9447e5fb027394e6c7a7bb3f331de26cd923799d Mon Sep 17 00:00:00 2001 From: Felix Barnsteiner Date: Thu, 12 Apr 2018 17:08:19 +0200 Subject: [PATCH 03/15] Separate web application from integration test Signed-off-by: Felix Barnsteiner --- .travis.yml | 3 ++ .../apm-servlet-plugin-it/pom.xml | 1 + .../simple-webapp-integration-test/pom.xml | 8 +--- .../AbstractTomcatIntegrationTest.java | 27 ++++++++---- .../simple-webapp/pom.xml | 41 +++++++++++++++++++ .../apm/servlet/ApmTestHelperServlet.java | 0 .../src/main/resources/logback.xml | 0 .../src/main/webapp/WEB-INF/web.xml | 0 .../src/main/webapp/index.jsp | 0 9 files changed, 66 insertions(+), 14 deletions(-) create mode 100644 apm-agent-plugins/apm-servlet-plugin-it/simple-webapp/pom.xml rename apm-agent-plugins/apm-servlet-plugin-it/{simple-webapp-integration-test => simple-webapp}/src/main/java/co/elastic/apm/servlet/ApmTestHelperServlet.java (100%) rename apm-agent-plugins/apm-servlet-plugin-it/{simple-webapp-integration-test => simple-webapp}/src/main/resources/logback.xml (100%) rename apm-agent-plugins/apm-servlet-plugin-it/{simple-webapp-integration-test => simple-webapp}/src/main/webapp/WEB-INF/web.xml (100%) rename apm-agent-plugins/apm-servlet-plugin-it/{simple-webapp-integration-test => simple-webapp}/src/main/webapp/index.jsp (100%) diff --git a/.travis.yml b/.travis.yml index 1dfe611681..8be4af030c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,6 @@ +sudo: true +services: + - docker language: java jdk: - oraclejdk9 diff --git a/apm-agent-plugins/apm-servlet-plugin-it/pom.xml b/apm-agent-plugins/apm-servlet-plugin-it/pom.xml index d7495af9f8..02878bfca1 100644 --- a/apm-agent-plugins/apm-servlet-plugin-it/pom.xml +++ b/apm-agent-plugins/apm-servlet-plugin-it/pom.xml @@ -13,6 +13,7 @@ pom ${project.groupId}:${project.artifactId} + simple-webapp simple-webapp-integration-test diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/pom.xml b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/pom.xml index 5037054ce6..d14539dd5b 100644 --- a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/pom.xml +++ b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/pom.xml @@ -10,19 +10,15 @@ 4.0.0 simple-webapp-integration-test - war ${project.groupId}:${project.artifactId} - - ROOT - - ${project.groupId} - apm-servlet-plugin + simple-webapp ${project.version} + war javax.servlet diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java index 53c026e0c2..b65b7629fd 100644 --- a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java +++ b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java @@ -48,6 +48,21 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockserver.model.HttpRequest.request; +/** + * When you want to execute the test in the IDE, execute {@code mvn clean package} before. + * This creates the {@code ROOT.war} file, + * which is bound into the docker container. + *

+ * Whenever you make changes to the application, + * you have to rerun {@code mvn clean package}. + *

+ *

+ * To debug simple-webapp which is deployed to tomcat, + * add a break point in {@link #setUp()} and evaluate tomcatContainer.getMappedPort(8000). + * Then create a remote debug configuration in IntelliJ using this port and start debugging. + * TODO use {@link org.testcontainers.containers.SocatContainer} to always have the same debugging port + *

+ */ public abstract class AbstractTomcatIntegrationTest { private static final Logger logger = LoggerFactory.getLogger(ServletIntegrationTest.class); @@ -55,22 +70,18 @@ public abstract class AbstractTomcatIntegrationTest { protected static GenericContainer tomcatContainer = new GenericContainer<>( new ImageFromDockerfile() .withDockerfileFromBuilder(builder -> builder - .from("tomcat:9") + .from("tomcat:8") + .env("JPDA_ADDRESS", "8000") + .env("JPDA_TRANSPORT", "dt_socket") .run("rm -rf /usr/local/tomcat/webapps/*") .expose(8080, 8000) .entryPoint("catalina.sh", "jpda", "run"))) .withNetwork(Network.SHARED) - // TODO debugging does not work - // to get the randomized debugger port, evaluate tomcatContainer.getMappedPort(8000) - // then create a remote debug configuration in IntelliJ using this port - // Error running 'Debug': Unable to open debugger port (localhost:33049): java.io.IOException "handshake failed - connection prematurally closed".withEnv("JPDA_ADDRESS", "8000") - .withEnv("JPDA_TRANSPORT", "dt_socket") .withEnv("ELASTIC_APM_SERVER_URL", "http://apm-server:1080") .withEnv("ELASTIC_APM_SERVICE_NAME", "servlet-test-app") .withEnv("ELASTIC_APM_IGNORE_URLS", "/apm/*") .withLogConsumer(new Slf4jLogConsumer(logger)) - // TODO chicken egg problem here: tests require the war to be present, which is built via mvn package, but mvn package executes the tests - .withFileSystemBind("target/ROOT.war", "/usr/local/tomcat/webapps/ROOT.war") + .withFileSystemBind("../simple-webapp/target/ROOT.war", "/usr/local/tomcat/webapps/ROOT.war") .withExposedPorts(8080, 8000); protected static MockServerContainer mockServerContainer = new MockServerContainer() .withNetworkAliases("apm-server") diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp/pom.xml b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp/pom.xml new file mode 100644 index 0000000000..297f92b89b --- /dev/null +++ b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp/pom.xml @@ -0,0 +1,41 @@ + + + + + apm-servlet-plugin-it + co.elastic.apm + 0.1.2-SNAPSHOT + + 4.0.0 + + simple-webapp + war + + ${project.groupId}:${project.artifactId} + + + ROOT + + + + + ${project.groupId} + apm-agent-java + ${project.version} + jar + + + javax.servlet + javax.servlet-api + 3.0.1 + provided + + + ch.qos.logback + logback-classic + ${version.logback} + + + + diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/main/java/co/elastic/apm/servlet/ApmTestHelperServlet.java b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp/src/main/java/co/elastic/apm/servlet/ApmTestHelperServlet.java similarity index 100% rename from apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/main/java/co/elastic/apm/servlet/ApmTestHelperServlet.java rename to apm-agent-plugins/apm-servlet-plugin-it/simple-webapp/src/main/java/co/elastic/apm/servlet/ApmTestHelperServlet.java diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/main/resources/logback.xml b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp/src/main/resources/logback.xml similarity index 100% rename from apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/main/resources/logback.xml rename to apm-agent-plugins/apm-servlet-plugin-it/simple-webapp/src/main/resources/logback.xml diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/main/webapp/WEB-INF/web.xml b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp/src/main/webapp/WEB-INF/web.xml similarity index 100% rename from apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/main/webapp/WEB-INF/web.xml rename to apm-agent-plugins/apm-servlet-plugin-it/simple-webapp/src/main/webapp/WEB-INF/web.xml diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/main/webapp/index.jsp b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp/src/main/webapp/index.jsp similarity index 100% rename from apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/main/webapp/index.jsp rename to apm-agent-plugins/apm-servlet-plugin-it/simple-webapp/src/main/webapp/index.jsp From 3d880156625534a54d16e63884f95e43c11ca2b9 Mon Sep 17 00:00:00 2001 From: Felix Barnsteiner Date: Fri, 13 Apr 2018 08:58:40 +0200 Subject: [PATCH 04/15] some small fixups --- .../simple-webapp-integration-test/pom.xml | 6 ------ .../src/test/resources/logback-test.xml | 1 - .../apm-servlet-plugin-it/simple-webapp/pom.xml | 1 - 3 files changed, 8 deletions(-) diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/pom.xml b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/pom.xml index d14539dd5b..b96869c2e1 100644 --- a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/pom.xml +++ b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/pom.xml @@ -20,12 +20,6 @@ ${project.version} war
- - javax.servlet - javax.servlet-api - 3.0.1 - provided - ch.qos.logback logback-classic diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/resources/logback-test.xml b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/resources/logback-test.xml index 074bd32c18..9c263a5e79 100644 --- a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/resources/logback-test.xml +++ b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/resources/logback-test.xml @@ -18,5 +18,4 @@ - diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp/pom.xml b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp/pom.xml index 297f92b89b..8a70ef0f91 100644 --- a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp/pom.xml +++ b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp/pom.xml @@ -23,7 +23,6 @@ ${project.groupId} apm-agent-java ${project.version} - jar javax.servlet From e40324afdd669893c2c5f4ead2720a97316cf66d Mon Sep 17 00:00:00 2001 From: Felix Barnsteiner Date: Fri, 13 Apr 2018 09:40:24 +0200 Subject: [PATCH 05/15] add assertion on response code --- .../co/elastic/apm/servlet/ServletIntegrationTest.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/ServletIntegrationTest.java b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/ServletIntegrationTest.java index 8b35cc410d..9b252cf71b 100644 --- a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/ServletIntegrationTest.java +++ b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/ServletIntegrationTest.java @@ -21,6 +21,7 @@ import com.fasterxml.jackson.databind.JsonNode; import okhttp3.Request; +import okhttp3.Response; import okhttp3.ResponseBody; import org.junit.Test; @@ -32,13 +33,14 @@ public class ServletIntegrationTest extends AbstractTomcatIntegrationTest { @Test public void testTransactionReporting() throws Exception { - final ResponseBody responseBody = httpClient.newCall(new Request.Builder() + final Response response = httpClient.newCall(new Request.Builder() .get() .url("http://" + tomcatContainer.getContainerIpAddress() + ":" + tomcatContainer.getMappedPort(8080) + "/index.jsp") .build()) - .execute() - .body(); + .execute(); + assertThat(response.code()).isEqualTo(200); + final ResponseBody responseBody = response.body(); assertThat(responseBody).isNotNull(); assertThat(responseBody.string()).contains("Hello World"); From 5d3a52687099bb1d4ad83dd592146c6cbb513d87 Mon Sep 17 00:00:00 2001 From: Felix Barnsteiner Date: Fri, 13 Apr 2018 10:06:31 +0200 Subject: [PATCH 06/15] add logging of http requests --- .../elastic/apm/servlet/AbstractTomcatIntegrationTest.java | 6 +++++- .../java/co/elastic/apm/servlet/ServletIntegrationTest.java | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java index b65b7629fd..b31ac5206d 100644 --- a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java +++ b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java @@ -28,6 +28,7 @@ import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; +import okhttp3.logging.HttpLoggingInterceptor; import org.junit.Before; import org.junit.BeforeClass; import org.mockserver.model.HttpRequest; @@ -91,7 +92,7 @@ public abstract class AbstractTomcatIntegrationTest { Stream.of(tomcatContainer, mockServerContainer).parallel().forEach(GenericContainer::start); } - protected OkHttpClient httpClient = new OkHttpClient.Builder().build(); + protected OkHttpClient httpClient; private JsonSchema schema; @@ -104,6 +105,9 @@ public static void beforeClass() { @Before public void setUp() { schema = JsonSchemaFactory.getInstance().getSchema(getClass().getResourceAsStream("/schema/transactions/payload.json")); + final HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(logger::info); + loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + httpClient = new OkHttpClient.Builder().addInterceptor(loggingInterceptor).build(); } protected List getReportedTransactions() throws IOException { diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/ServletIntegrationTest.java b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/ServletIntegrationTest.java index 9b252cf71b..a53e22abb4 100644 --- a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/ServletIntegrationTest.java +++ b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/ServletIntegrationTest.java @@ -39,7 +39,7 @@ public void testTransactionReporting() throws Exception { .build()) .execute(); - assertThat(response.code()).isEqualTo(200); + assertThat(response.code()).withFailMessage(response.toString()).isEqualTo(200); final ResponseBody responseBody = response.body(); assertThat(responseBody).isNotNull(); assertThat(responseBody.string()).contains("Hello World"); From bb0c1e29d0a1c05b1802c00684c795235e69e95b Mon Sep 17 00:00:00 2001 From: Felix Barnsteiner Date: Fri, 13 Apr 2018 10:45:38 +0200 Subject: [PATCH 07/15] Assert that war file exists Signed-off-by: Felix Barnsteiner --- .../AbstractTomcatIntegrationTest.java | 9 ++- .../apm/servlet/StandardOutLogConsumer.java | 65 +++++++++++++++++++ 2 files changed, 71 insertions(+), 3 deletions(-) create mode 100644 apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/StandardOutLogConsumer.java diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java index b31ac5206d..2ad7802192 100644 --- a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java +++ b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java @@ -37,9 +37,9 @@ import org.slf4j.LoggerFactory; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.output.Slf4jLogConsumer; import org.testcontainers.images.builder.ImageFromDockerfile; +import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -68,6 +68,7 @@ public abstract class AbstractTomcatIntegrationTest { private static final Logger logger = LoggerFactory.getLogger(ServletIntegrationTest.class); + private static final String pathToWar = "../simple-webapp/target/ROOT.war"; protected static GenericContainer tomcatContainer = new GenericContainer<>( new ImageFromDockerfile() .withDockerfileFromBuilder(builder -> builder @@ -81,14 +82,16 @@ public abstract class AbstractTomcatIntegrationTest { .withEnv("ELASTIC_APM_SERVER_URL", "http://apm-server:1080") .withEnv("ELASTIC_APM_SERVICE_NAME", "servlet-test-app") .withEnv("ELASTIC_APM_IGNORE_URLS", "/apm/*") - .withLogConsumer(new Slf4jLogConsumer(logger)) - .withFileSystemBind("../simple-webapp/target/ROOT.war", "/usr/local/tomcat/webapps/ROOT.war") + .withLogConsumer(new StandardOutLogConsumer().withPrefix("tomcat")) + .withFileSystemBind(pathToWar, "/usr/local/tomcat/webapps/ROOT.war") .withExposedPorts(8080, 8000); protected static MockServerContainer mockServerContainer = new MockServerContainer() .withNetworkAliases("apm-server") .withNetwork(Network.SHARED); static { + final File warFile = new File(pathToWar); + assertThat(warFile).withFailMessage(warFile.getAbsolutePath()).exists(); Stream.of(tomcatContainer, mockServerContainer).parallel().forEach(GenericContainer::start); } diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/StandardOutLogConsumer.java b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/StandardOutLogConsumer.java new file mode 100644 index 0000000000..572e913423 --- /dev/null +++ b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/StandardOutLogConsumer.java @@ -0,0 +1,65 @@ +/*- + * #%L + * Elastic APM Java agent + * %% + * Copyright (C) 2018 the original author or authors + * %% + * 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.servlet; + +import org.testcontainers.containers.output.OutputFrame; + +import java.util.function.Consumer; +import java.util.regex.Pattern; + +public class StandardOutLogConsumer implements Consumer { + private static final Pattern ANSI_CODE_PATTERN = Pattern.compile("\\[\\d[ABCD]"); + private String prefix = ""; + + public StandardOutLogConsumer() { + } + + public StandardOutLogConsumer withPrefix(String prefix) { + this.prefix = "[" + prefix + "] "; + return this; + } + + @Override + public void accept(OutputFrame outputFrame) { + if (outputFrame != null) { + String utf8String = outputFrame.getUtf8String(); + + if (utf8String != null) { + OutputFrame.OutputType outputType = outputFrame.getType(); + String message = utf8String.trim(); + + if (ANSI_CODE_PATTERN.matcher(message).matches()) { + return; + } + + switch (outputType) { + case END: + break; + case STDOUT: + case STDERR: + System.out.println(String.format("%s%s", prefix, message)); + break; + default: + throw new IllegalArgumentException("Unexpected outputType " + outputType); + } + } + } + } +} From 8c3de0b9a58755257fd38d42fcf0a9e4d1435696 Mon Sep 17 00:00:00 2001 From: Felix Barnsteiner Date: Fri, 13 Apr 2018 11:10:16 +0200 Subject: [PATCH 08/15] add more assertions regarding the war file --- .../elastic/apm/servlet/AbstractTomcatIntegrationTest.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java index 2ad7802192..643914f68e 100644 --- a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java +++ b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java @@ -68,7 +68,7 @@ public abstract class AbstractTomcatIntegrationTest { private static final Logger logger = LoggerFactory.getLogger(ServletIntegrationTest.class); - private static final String pathToWar = "../simple-webapp/target/ROOT.war"; + private static final String pathToWar = "../simple-webapp/taget/ROOT.war"; protected static GenericContainer tomcatContainer = new GenericContainer<>( new ImageFromDockerfile() .withDockerfileFromBuilder(builder -> builder @@ -91,7 +91,10 @@ public abstract class AbstractTomcatIntegrationTest { static { final File warFile = new File(pathToWar); - assertThat(warFile).withFailMessage(warFile.getAbsolutePath()).exists(); + logger.info("Check file {}", warFile); + assertThat(warFile).exists(); + assertThat(warFile).isFile(); + assertThat(warFile.length()).isGreaterThan(0); Stream.of(tomcatContainer, mockServerContainer).parallel().forEach(GenericContainer::start); } From bd2c932b77974a58609607109f876d8e076ced83 Mon Sep 17 00:00:00 2001 From: Felix Barnsteiner Date: Fri, 13 Apr 2018 11:14:25 +0200 Subject: [PATCH 09/15] Fix path to war --- .../co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java index 643914f68e..01ce512287 100644 --- a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java +++ b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java @@ -68,7 +68,7 @@ public abstract class AbstractTomcatIntegrationTest { private static final Logger logger = LoggerFactory.getLogger(ServletIntegrationTest.class); - private static final String pathToWar = "../simple-webapp/taget/ROOT.war"; + private static final String pathToWar = "../simple-webapp/target/ROOT.war"; protected static GenericContainer tomcatContainer = new GenericContainer<>( new ImageFromDockerfile() .withDockerfileFromBuilder(builder -> builder From 88c0fd38b8f8c7d8766a57f04e7c9cbd59a040c3 Mon Sep 17 00:00:00 2001 From: Felix Barnsteiner Date: Fri, 13 Apr 2018 11:35:23 +0200 Subject: [PATCH 10/15] Log message on servlet init to see if the application has started properly Signed-off-by: Felix Barnsteiner --- .../elastic/apm/servlet/AbstractTomcatIntegrationTest.java | 2 +- .../java/co/elastic/apm/servlet/ApmTestHelperServlet.java | 7 +++++++ .../simple-webapp/src/main/webapp/WEB-INF/web.xml | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java index 01ce512287..307f4f3298 100644 --- a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java +++ b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java @@ -91,7 +91,7 @@ public abstract class AbstractTomcatIntegrationTest { static { final File warFile = new File(pathToWar); - logger.info("Check file {}", warFile); + logger.info("Check file {}", warFile.getAbsolutePath()); assertThat(warFile).exists(); assertThat(warFile).isFile(); assertThat(warFile.length()).isGreaterThan(0); diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp/src/main/java/co/elastic/apm/servlet/ApmTestHelperServlet.java b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp/src/main/java/co/elastic/apm/servlet/ApmTestHelperServlet.java index 7ad890fea0..f543bd7255 100644 --- a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp/src/main/java/co/elastic/apm/servlet/ApmTestHelperServlet.java +++ b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp/src/main/java/co/elastic/apm/servlet/ApmTestHelperServlet.java @@ -23,6 +23,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; @@ -33,6 +34,12 @@ public class ApmTestHelperServlet extends HttpServlet { private static final Logger logger = LoggerFactory.getLogger(ApmTestHelperServlet.class); private final ElasticApmTracer tracer = ElasticApmTracer.get(); + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + logger.info("APM test application {} started", config.getServletContext().getServletContextName()); + } + @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException { try { diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp/src/main/webapp/WEB-INF/web.xml b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp/src/main/webapp/WEB-INF/web.xml index 5b81707e7f..d1c2e925ba 100644 --- a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp/src/main/webapp/WEB-INF/web.xml +++ b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp/src/main/webapp/WEB-INF/web.xml @@ -15,6 +15,7 @@ ApmTestHelperServlet co.elastic.apm.servlet.ApmTestHelperServlet + 1 ApmTestHelperServlet From 2db230e98f7ecc4dd58de143a3d62a84e36d00d9 Mon Sep 17 00:00:00 2001 From: Felix Barnsteiner Date: Wed, 25 Apr 2018 16:03:13 +0200 Subject: [PATCH 11/15] Turn on debug logs for dockerjava to see what it actually tries to bind Signed-off-by: Felix Barnsteiner --- .../src/test/resources/logback-test.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/resources/logback-test.xml b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/resources/logback-test.xml index 9c263a5e79..520fb27239 100644 --- a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/resources/logback-test.xml +++ b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/resources/logback-test.xml @@ -17,5 +17,5 @@ - + From f2f80c2b8a87a1954eb3c5f758f689ba348d5676 Mon Sep 17 00:00:00 2001 From: Felix Barnsteiner Date: Wed, 25 Apr 2018 16:15:09 +0200 Subject: [PATCH 12/15] Update testcontainers Signed-off-by: Felix Barnsteiner --- .../simple-webapp-integration-test/pom.xml | 2 +- .../src/test/resources/logback-test.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/pom.xml b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/pom.xml index b96869c2e1..e074840e54 100644 --- a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/pom.xml +++ b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/pom.xml @@ -28,7 +28,7 @@ org.testcontainers testcontainers - 1.7.0 + 1.7.1 test diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/resources/logback-test.xml b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/resources/logback-test.xml index 520fb27239..9c263a5e79 100644 --- a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/resources/logback-test.xml +++ b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/resources/logback-test.xml @@ -17,5 +17,5 @@ - + From 0d4acc4a89b4f5a73f8d6f3cb28a7118ca914d5d Mon Sep 17 00:00:00 2001 From: Felix Barnsteiner Date: Thu, 26 Apr 2018 11:12:37 +0200 Subject: [PATCH 13/15] Add report_sync configuration option Useful for integration tests to ensure the transactions have been reported Signed-off-by: Felix Barnsteiner --- .../co/elastic/apm/report/ApmServerReporter.java | 16 ++++++++++++++++ .../apm/report/ReporterConfiguration.java | 15 ++++++++++++--- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/apm-agent-core/src/main/java/co/elastic/apm/report/ApmServerReporter.java b/apm-agent-core/src/main/java/co/elastic/apm/report/ApmServerReporter.java index 7ab619497f..85179c370d 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/report/ApmServerReporter.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/report/ApmServerReporter.java @@ -72,6 +72,7 @@ public void translateTo(ReportingEvent event, long sequence, ErrorCapture error) private final AtomicInteger dropped = new AtomicInteger(); private final boolean dropTransactionIfQueueFull; private final ReportingEventHandler reportingEventHandler; + private final boolean syncReport; @Nullable private ScheduledThreadPoolExecutor flushScheduler; @@ -79,6 +80,7 @@ public ApmServerReporter(Service service, ProcessInfo process, SystemInfo system boolean dropTransactionIfQueueFull, ReporterConfiguration reporterConfiguration, ProcessorEventHandler processorEventHandler) { this.dropTransactionIfQueueFull = dropTransactionIfQueueFull; + this.syncReport = reporterConfiguration.isReportSynchronously(); disruptor = new Disruptor<>(new TransactionEventFactory(), MathUtils.getNextPowerOf2(reporterConfiguration.getMaxQueueSize()), new ThreadFactory() { @Override public Thread newThread(Runnable r) { @@ -109,6 +111,17 @@ public void report(Transaction transaction) { if (!tryAddEventToRingBuffer(transaction, TRANSACTION_EVENT_TRANSLATOR)) { transaction.recycle(); } + if (syncReport) { + waitForFlush(); + } + } + + private void waitForFlush() { + try { + flush().get(); + } catch (Exception e) { + throw new RuntimeException(e); + } } @Override @@ -185,6 +198,9 @@ public void report(ErrorCapture error) { if (!tryAddEventToRingBuffer(error, ERROR_EVENT_TRANSLATOR)) { error.recycle(); } + if (syncReport) { + waitForFlush(); + } } private boolean tryAddEventToRingBuffer(E event, EventTranslatorOneArg eventTranslator) { diff --git a/apm-agent-core/src/main/java/co/elastic/apm/report/ReporterConfiguration.java b/apm-agent-core/src/main/java/co/elastic/apm/report/ReporterConfiguration.java index 7fd0c97a3e..61cf04537d 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/report/ReporterConfiguration.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/report/ReporterConfiguration.java @@ -25,9 +25,6 @@ import javax.annotation.Nullable; import java.net.URL; -import java.util.Collection; -import java.util.Collections; -import java.util.List; public class ReporterConfiguration extends ConfigurationOptionProvider { public static final String REPORTER_CATEGORY = "Reporter"; @@ -86,6 +83,14 @@ public class ReporterConfiguration extends ConfigurationOptionProvider { .dynamic(true) .buildWithDefault(500); + private final ConfigurationOption reportSynchronously = ConfigurationOption.booleanOption() + .key("report_sync") + .tags("internal") + .configurationCategory(REPORTER_CATEGORY) + .description("Only to be used for testing purposes. " + + "Blocks the requests until the transaction has been reported to the APM server.") + .buildWithDefault(false); + @Nullable public String getSecretToken() { return secretToken.get(); @@ -110,4 +115,8 @@ public int getFlushInterval() { public int getMaxQueueSize() { return maxQueueSize.get(); } + + public boolean isReportSynchronously() { + return reportSynchronously.get(); + } } From 13a82fdd029898256283a57c003f2b1883b388b8 Mon Sep 17 00:00:00 2001 From: Felix Barnsteiner Date: Thu, 26 Apr 2018 11:29:12 +0200 Subject: [PATCH 14/15] Deploy war file with copyFileToContainer This works around a bug in docker-java which encodes the plus sign to a space when binding a file to the container. Also restructures the integration tests into a top-level integration-tests module as it felt a bit awkward as a apm-agent-plugins submodule. It's not a plugin and we want to avoid packaging the tests applications like simple-webapp into the main distribution. Signed-off-by: Felix Barnsteiner --- apm-agent-core/pom.xml | 5 +- .../test/resources/configuration.asciidoc.ftl | 2 + .../apm/servlet/ApmTestHelperServlet.java | 56 ------------------- apm-agent-plugins/pom.xml | 1 - .../pom.xml | 10 ++-- .../simple-webapp-integration-test/pom.xml | 19 ++++++- .../AbstractTomcatIntegrationTest.java | 56 +++++++------------ .../apm/servlet/MockServerContainer.java | 0 .../apm/servlet/ServletIntegrationTest.java | 6 ++ .../apm/servlet/StandardOutLogConsumer.java | 0 .../src/test/resources/logback-test.xml | 0 .../simple-webapp/pom.xml | 14 ++++- .../src/main/resources/logback.xml | 0 .../src/main/webapp/WEB-INF/web.xml | 9 --- .../simple-webapp/src/main/webapp/index.jsp | 0 .../simple-webapp/src/main/webapp/status.jsp | 1 + pom.xml | 2 + 17 files changed, 67 insertions(+), 114 deletions(-) delete mode 100644 apm-agent-plugins/apm-servlet-plugin-it/simple-webapp/src/main/java/co/elastic/apm/servlet/ApmTestHelperServlet.java rename {apm-agent-plugins/apm-servlet-plugin-it => integration-tests}/pom.xml (71%) rename {apm-agent-plugins/apm-servlet-plugin-it => integration-tests}/simple-webapp-integration-test/pom.xml (75%) rename {apm-agent-plugins/apm-servlet-plugin-it => integration-tests}/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java (79%) rename {apm-agent-plugins/apm-servlet-plugin-it => integration-tests}/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/MockServerContainer.java (100%) rename {apm-agent-plugins/apm-servlet-plugin-it => integration-tests}/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/ServletIntegrationTest.java (93%) rename {apm-agent-plugins/apm-servlet-plugin-it => integration-tests}/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/StandardOutLogConsumer.java (100%) rename {apm-agent-plugins/apm-servlet-plugin-it => integration-tests}/simple-webapp-integration-test/src/test/resources/logback-test.xml (100%) rename {apm-agent-plugins/apm-servlet-plugin-it => integration-tests}/simple-webapp/pom.xml (73%) rename {apm-agent-plugins/apm-servlet-plugin-it => integration-tests}/simple-webapp/src/main/resources/logback.xml (100%) rename {apm-agent-plugins/apm-servlet-plugin-it => integration-tests}/simple-webapp/src/main/webapp/WEB-INF/web.xml (56%) rename {apm-agent-plugins/apm-servlet-plugin-it => integration-tests}/simple-webapp/src/main/webapp/index.jsp (100%) create mode 100644 integration-tests/simple-webapp/src/main/webapp/status.jsp diff --git a/apm-agent-core/pom.xml b/apm-agent-core/pom.xml index b2584b1aaf..4222592082 100644 --- a/apm-agent-core/pom.xml +++ b/apm-agent-core/pom.xml @@ -3,7 +3,6 @@ 4.0.0 true - 3.9.1 @@ -63,12 +62,12 @@ com.squareup.okhttp3 okhttp - ${okhttp.version} + ${version.okhttp} com.squareup.okhttp3 logging-interceptor - ${okhttp.version} + ${version.okhttp} com.lmax diff --git a/apm-agent-java/src/test/resources/configuration.asciidoc.ftl b/apm-agent-java/src/test/resources/configuration.asciidoc.ftl index 4a3a2aa64b..b9e7b496cd 100644 --- a/apm-agent-java/src/test/resources/configuration.asciidoc.ftl +++ b/apm-agent-java/src/test/resources/configuration.asciidoc.ftl @@ -36,6 +36,7 @@ application_packages=org.example [[${category?lower_case?replace(" ", "-")}]] === ${category} configuration options <#list options as option> + <#if !option.tags?seq_contains("internal")> [float] [[config-${option.key?replace("[^a-z]", "-", "r")}]] ==== `${option.key}` @@ -56,6 +57,7 @@ ${option.description} | `elastic.apm.${option.key}` | `ELASTIC_APM_${option.key?upper_case}` | `${option.key}` |============ + diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp/src/main/java/co/elastic/apm/servlet/ApmTestHelperServlet.java b/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp/src/main/java/co/elastic/apm/servlet/ApmTestHelperServlet.java deleted file mode 100644 index f543bd7255..0000000000 --- a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp/src/main/java/co/elastic/apm/servlet/ApmTestHelperServlet.java +++ /dev/null @@ -1,56 +0,0 @@ -/*- - * #%L - * Elastic APM Java agent - * %% - * Copyright (C) 2018 the original author or authors - * %% - * 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.servlet; - -import co.elastic.apm.impl.ElasticApmTracer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -public class ApmTestHelperServlet extends HttpServlet { - - private static final Logger logger = LoggerFactory.getLogger(ApmTestHelperServlet.class); - private final ElasticApmTracer tracer = ElasticApmTracer.get(); - - @Override - public void init(ServletConfig config) throws ServletException { - super.init(config); - logger.info("APM test application {} started", config.getServletContext().getServletContextName()); - } - - @Override - protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException { - try { - switch (req.getPathInfo()) { - case "/flush": - logger.info("Flushing reporter"); - tracer.getReporter().flush().get(); - break; - } - } catch (Exception e) { - throw new ServletException(e); - } - } -} diff --git a/apm-agent-plugins/pom.xml b/apm-agent-plugins/pom.xml index bf4a84913e..de49585bfd 100644 --- a/apm-agent-plugins/pom.xml +++ b/apm-agent-plugins/pom.xml @@ -9,7 +9,6 @@ pom apm-servlet-plugin - apm-servlet-plugin-it apm-web-plugin apm-jdbc-plugin apm-spring-webmvc-plugin diff --git a/apm-agent-plugins/apm-servlet-plugin-it/pom.xml b/integration-tests/pom.xml similarity index 71% rename from apm-agent-plugins/apm-servlet-plugin-it/pom.xml rename to integration-tests/pom.xml index 02878bfca1..c28504e041 100644 --- a/apm-agent-plugins/apm-servlet-plugin-it/pom.xml +++ b/integration-tests/pom.xml @@ -3,19 +3,21 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - apm-agent-plugins + apm-agent-parent co.elastic.apm - 0.1.2-SNAPSHOT + 0.1.3-SNAPSHOT 4.0.0 - apm-servlet-plugin-it + integration-tests pom ${project.groupId}:${project.artifactId} simple-webapp simple-webapp-integration-test - + + true + diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/pom.xml b/integration-tests/simple-webapp-integration-test/pom.xml similarity index 75% rename from apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/pom.xml rename to integration-tests/simple-webapp-integration-test/pom.xml index e074840e54..72825915e0 100644 --- a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/pom.xml +++ b/integration-tests/simple-webapp-integration-test/pom.xml @@ -3,9 +3,9 @@ - apm-servlet-plugin-it + integration-tests co.elastic.apm - 0.1.2-SNAPSHOT + 0.1.3-SNAPSHOT 4.0.0 @@ -20,6 +20,21 @@ ${project.version} war + + ${project.groupId} + apm-agent-core + ${project.version} + + + com.squareup.okhttp3 + okhttp + ${version.okhttp} + + + com.squareup.okhttp3 + logging-interceptor + ${version.okhttp} + ch.qos.logback logback-classic diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java b/integration-tests/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java similarity index 79% rename from apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java rename to integration-tests/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java index 307f4f3298..25eeff5f81 100644 --- a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java +++ b/integration-tests/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java @@ -24,12 +24,8 @@ import com.networknt.schema.JsonSchema; import com.networknt.schema.JsonSchemaFactory; import com.networknt.schema.ValidationMessage; -import okhttp3.HttpUrl; import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.RequestBody; import okhttp3.logging.HttpLoggingInterceptor; -import org.junit.Before; import org.junit.BeforeClass; import org.mockserver.model.HttpRequest; import org.mockserver.model.HttpResponse; @@ -37,7 +33,9 @@ import org.slf4j.LoggerFactory; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; +import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.images.builder.ImageFromDockerfile; +import org.testcontainers.utility.MountableFile; import java.io.File; import java.io.IOException; @@ -59,7 +57,7 @@ *

*

* To debug simple-webapp which is deployed to tomcat, - * add a break point in {@link #setUp()} and evaluate tomcatContainer.getMappedPort(8000). + * add a break point in {@link #beforeClass()} and evaluate tomcatContainer.getMappedPort(8000). * Then create a remote debug configuration in IntelliJ using this port and start debugging. * TODO use {@link org.testcontainers.containers.SocatContainer} to always have the same debugging port *

@@ -81,43 +79,42 @@ public abstract class AbstractTomcatIntegrationTest { .withNetwork(Network.SHARED) .withEnv("ELASTIC_APM_SERVER_URL", "http://apm-server:1080") .withEnv("ELASTIC_APM_SERVICE_NAME", "servlet-test-app") - .withEnv("ELASTIC_APM_IGNORE_URLS", "/apm/*") + .withEnv("ELASTIC_APM_IGNORE_URLS", "/status*,/favicon.ico") + .withEnv("ELASTIC_APM_REPORT_SYNC", "true") .withLogConsumer(new StandardOutLogConsumer().withPrefix("tomcat")) - .withFileSystemBind(pathToWar, "/usr/local/tomcat/webapps/ROOT.war") .withExposedPorts(8080, 8000); protected static MockServerContainer mockServerContainer = new MockServerContainer() .withNetworkAliases("apm-server") .withNetwork(Network.SHARED); + protected static OkHttpClient httpClient; + private static JsonSchema schema; static { - final File warFile = new File(pathToWar); - logger.info("Check file {}", warFile.getAbsolutePath()); - assertThat(warFile).exists(); - assertThat(warFile).isFile(); - assertThat(warFile.length()).isGreaterThan(0); Stream.of(tomcatContainer, mockServerContainer).parallel().forEach(GenericContainer::start); } - protected OkHttpClient httpClient; - private JsonSchema schema; - - @BeforeClass public static void beforeClass() { mockServerContainer.getClient().when(request("/v1/transactions")).respond(HttpResponse.response().withStatusCode(200)); mockServerContainer.getClient().when(request("/v1/errors")).respond(HttpResponse.response().withStatusCode(200)); - } - - @Before - public void setUp() { - schema = JsonSchemaFactory.getInstance().getSchema(getClass().getResourceAsStream("/schema/transactions/payload.json")); + schema = JsonSchemaFactory.getInstance().getSchema( + AbstractTomcatIntegrationTest.class.getResourceAsStream("/schema/transactions/payload.json")); final HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(logger::info); loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY); httpClient = new OkHttpClient.Builder().addInterceptor(loggingInterceptor).build(); } + protected void deployWarFile(String pathToWar, String status) { + final File warFile = new File(pathToWar); + assertThat(warFile).exists(); + assertThat(warFile).isFile(); + assertThat(warFile.length()).isGreaterThan(0); + // TODO remove with withFileSystemBind when a new docker-java version is released + tomcatContainer.copyFileToContainer(MountableFile.forHostPath(pathToWar), "/usr/local/tomcat/webapps/"); + Wait.forHttp(status).waitUntilReady(tomcatContainer); + } + protected List getReportedTransactions() throws IOException { - flushReporterQueue(); final List transactions = new ArrayList<>(); final ObjectMapper objectMapper = new ObjectMapper(); for (HttpRequest httpRequest : mockServerContainer.getClient().retrieveRecordedRequests(request("/v1/transactions"))) { @@ -135,19 +132,4 @@ private void validateJsonSchema(JsonNode payload) { assertThat(errors).isEmpty(); } - /** - * Makes sure all pending items in the {@link co.elastic.apm.report.Reporter} queue are flushed to the APM server mock - */ - private void flushReporterQueue() throws IOException { - httpClient.newCall(new Request.Builder() - .post(RequestBody.create(null, new byte[0])) - .url(new HttpUrl.Builder() - .scheme("http") - .host(tomcatContainer.getContainerIpAddress()) - .port(tomcatContainer.getFirstMappedPort()) - .encodedPath("/apm/flush") - .build()) - .build()) - .execute(); - } } diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/MockServerContainer.java b/integration-tests/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/MockServerContainer.java similarity index 100% rename from apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/MockServerContainer.java rename to integration-tests/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/MockServerContainer.java diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/ServletIntegrationTest.java b/integration-tests/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/ServletIntegrationTest.java similarity index 93% rename from apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/ServletIntegrationTest.java rename to integration-tests/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/ServletIntegrationTest.java index a53e22abb4..fdbe815d75 100644 --- a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/ServletIntegrationTest.java +++ b/integration-tests/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/ServletIntegrationTest.java @@ -23,6 +23,7 @@ import okhttp3.Request; import okhttp3.Response; import okhttp3.ResponseBody; +import org.junit.Before; import org.junit.Test; import java.util.List; @@ -31,6 +32,11 @@ public class ServletIntegrationTest extends AbstractTomcatIntegrationTest { + @Before + public void setUp() { + deployWarFile("../simple-webapp/target/ROOT.war", "/status.jsp"); + } + @Test public void testTransactionReporting() throws Exception { final Response response = httpClient.newCall(new Request.Builder() diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/StandardOutLogConsumer.java b/integration-tests/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/StandardOutLogConsumer.java similarity index 100% rename from apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/StandardOutLogConsumer.java rename to integration-tests/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/StandardOutLogConsumer.java diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/resources/logback-test.xml b/integration-tests/simple-webapp-integration-test/src/test/resources/logback-test.xml similarity index 100% rename from apm-agent-plugins/apm-servlet-plugin-it/simple-webapp-integration-test/src/test/resources/logback-test.xml rename to integration-tests/simple-webapp-integration-test/src/test/resources/logback-test.xml diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp/pom.xml b/integration-tests/simple-webapp/pom.xml similarity index 73% rename from apm-agent-plugins/apm-servlet-plugin-it/simple-webapp/pom.xml rename to integration-tests/simple-webapp/pom.xml index 8a70ef0f91..9aebb9068c 100644 --- a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp/pom.xml +++ b/integration-tests/simple-webapp/pom.xml @@ -3,9 +3,9 @@ - apm-servlet-plugin-it + integration-tests co.elastic.apm - 0.1.2-SNAPSHOT + 0.1.3-SNAPSHOT 4.0.0 @@ -23,6 +23,16 @@ ${project.groupId} apm-agent-java ${project.version} + + + + * + * + +
javax.servlet diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp/src/main/resources/logback.xml b/integration-tests/simple-webapp/src/main/resources/logback.xml similarity index 100% rename from apm-agent-plugins/apm-servlet-plugin-it/simple-webapp/src/main/resources/logback.xml rename to integration-tests/simple-webapp/src/main/resources/logback.xml diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp/src/main/webapp/WEB-INF/web.xml b/integration-tests/simple-webapp/src/main/webapp/WEB-INF/web.xml similarity index 56% rename from apm-agent-plugins/apm-servlet-plugin-it/simple-webapp/src/main/webapp/WEB-INF/web.xml rename to integration-tests/simple-webapp/src/main/webapp/WEB-INF/web.xml index d1c2e925ba..4cd4e4a91a 100644 --- a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp/src/main/webapp/WEB-INF/web.xml +++ b/integration-tests/simple-webapp/src/main/webapp/WEB-INF/web.xml @@ -12,13 +12,4 @@ ApmFilter /* - - ApmTestHelperServlet - co.elastic.apm.servlet.ApmTestHelperServlet - 1 - - - ApmTestHelperServlet - /apm/* - diff --git a/apm-agent-plugins/apm-servlet-plugin-it/simple-webapp/src/main/webapp/index.jsp b/integration-tests/simple-webapp/src/main/webapp/index.jsp similarity index 100% rename from apm-agent-plugins/apm-servlet-plugin-it/simple-webapp/src/main/webapp/index.jsp rename to integration-tests/simple-webapp/src/main/webapp/index.jsp diff --git a/integration-tests/simple-webapp/src/main/webapp/status.jsp b/integration-tests/simple-webapp/src/main/webapp/status.jsp new file mode 100644 index 0000000000..d86bac9de5 --- /dev/null +++ b/integration-tests/simple-webapp/src/main/webapp/status.jsp @@ -0,0 +1 @@ +OK diff --git a/pom.xml b/pom.xml index c2bf95bc70..890d63de56 100644 --- a/pom.xml +++ b/pom.xml @@ -69,6 +69,7 @@ 5.1.1 1.2.3 0.1.19 + 3.9.1 @@ -78,6 +79,7 @@ apm-agent-plugins apm-agent-api apm-opentracing + integration-tests From 6fc7d9fea6760a8f8ab64698ea8461a7d8474134 Mon Sep 17 00:00:00 2001 From: Felix Barnsteiner Date: Mon, 30 Apr 2018 21:33:31 +0200 Subject: [PATCH 15/15] Update testcontainers - should now work apm-ci - Deploy war withFileSystemBind instead of copyFileToContainer as that is much faster (1s vs 8s) Signed-off-by: Felix Barnsteiner --- .../simple-webapp-integration-test/pom.xml | 2 +- .../servlet/AbstractTomcatIntegrationTest.java | 18 ++++++------------ .../apm/servlet/ServletIntegrationTest.java | 6 ------ 3 files changed, 7 insertions(+), 19 deletions(-) diff --git a/integration-tests/simple-webapp-integration-test/pom.xml b/integration-tests/simple-webapp-integration-test/pom.xml index 72825915e0..3bda4321e8 100644 --- a/integration-tests/simple-webapp-integration-test/pom.xml +++ b/integration-tests/simple-webapp-integration-test/pom.xml @@ -43,7 +43,7 @@ org.testcontainers testcontainers - 1.7.1 + 1.7.2 test diff --git a/integration-tests/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java b/integration-tests/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java index 25eeff5f81..1c212bfdcb 100644 --- a/integration-tests/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java +++ b/integration-tests/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/AbstractTomcatIntegrationTest.java @@ -33,9 +33,7 @@ import org.slf4j.LoggerFactory; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.images.builder.ImageFromDockerfile; -import org.testcontainers.utility.MountableFile; import java.io.File; import java.io.IOException; @@ -82,6 +80,7 @@ public abstract class AbstractTomcatIntegrationTest { .withEnv("ELASTIC_APM_IGNORE_URLS", "/status*,/favicon.ico") .withEnv("ELASTIC_APM_REPORT_SYNC", "true") .withLogConsumer(new StandardOutLogConsumer().withPrefix("tomcat")) + .withFileSystemBind(pathToWar, "/usr/local/tomcat/webapps/ROOT.war") .withExposedPorts(8080, 8000); protected static MockServerContainer mockServerContainer = new MockServerContainer() .withNetworkAliases("apm-server") @@ -90,6 +89,11 @@ public abstract class AbstractTomcatIntegrationTest { private static JsonSchema schema; static { + final File warFile = new File(pathToWar); + logger.info("Check file {}", warFile.getAbsolutePath()); + assertThat(warFile).exists(); + assertThat(warFile).isFile(); + assertThat(warFile.length()).isGreaterThan(0); Stream.of(tomcatContainer, mockServerContainer).parallel().forEach(GenericContainer::start); } @@ -104,16 +108,6 @@ public static void beforeClass() { httpClient = new OkHttpClient.Builder().addInterceptor(loggingInterceptor).build(); } - protected void deployWarFile(String pathToWar, String status) { - final File warFile = new File(pathToWar); - assertThat(warFile).exists(); - assertThat(warFile).isFile(); - assertThat(warFile.length()).isGreaterThan(0); - // TODO remove with withFileSystemBind when a new docker-java version is released - tomcatContainer.copyFileToContainer(MountableFile.forHostPath(pathToWar), "/usr/local/tomcat/webapps/"); - Wait.forHttp(status).waitUntilReady(tomcatContainer); - } - protected List getReportedTransactions() throws IOException { final List transactions = new ArrayList<>(); final ObjectMapper objectMapper = new ObjectMapper(); diff --git a/integration-tests/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/ServletIntegrationTest.java b/integration-tests/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/ServletIntegrationTest.java index fdbe815d75..a53e22abb4 100644 --- a/integration-tests/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/ServletIntegrationTest.java +++ b/integration-tests/simple-webapp-integration-test/src/test/java/co/elastic/apm/servlet/ServletIntegrationTest.java @@ -23,7 +23,6 @@ import okhttp3.Request; import okhttp3.Response; import okhttp3.ResponseBody; -import org.junit.Before; import org.junit.Test; import java.util.List; @@ -32,11 +31,6 @@ public class ServletIntegrationTest extends AbstractTomcatIntegrationTest { - @Before - public void setUp() { - deployWarFile("../simple-webapp/target/ROOT.war", "/status.jsp"); - } - @Test public void testTransactionReporting() throws Exception { final Response response = httpClient.newCall(new Request.Builder()