Skip to content

Commit

Permalink
Add support for GlassFish (#51)
Browse files Browse the repository at this point in the history
* Add support for GlassFish

* Update Tomcat to new images as well

* Format

* Simplify config

* Update to new images that use application with context path

* Polish

* Actually disable failing test for now
  • Loading branch information
iNikem authored Dec 7, 2020
1 parent 741d2b7 commit 83e64a6
Show file tree
Hide file tree
Showing 18 changed files with 217 additions and 33 deletions.
1 change: 1 addition & 0 deletions agent/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ tasks {

// relocate OpenTelemetry API
relocate("io.opentelemetry.api", "io.opentelemetry.javaagent.shaded.io.opentelemetry.api")
relocate("io.opentelemetry.spi", "io.opentelemetry.javaagent.shaded.io.opentelemetry.spi")
relocate("io.opentelemetry.context", "io.opentelemetry.javaagent.shaded.io.opentelemetry.context")

manifest {
Expand Down
4 changes: 2 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ subprojects {
apply(from = "$rootDir/gradle/spotless.gradle")

extra.set("versions", mapOf(
"opentelemetry" to "0.10.0",
"opentelemetryJavaagent" to "0.10.2"
"opentelemetry" to "0.12.0",
"opentelemetryJavaagent" to "0.12.0-SNAPSHOT"
))

repositories {
Expand Down
1 change: 1 addition & 0 deletions custom/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ tasks {

// relocate OpenTelemetry API
relocate("io.opentelemetry.api", "io.opentelemetry.javaagent.shaded.io.opentelemetry.api")
relocate("io.opentelemetry.spi", "io.opentelemetry.javaagent.shaded.io.opentelemetry.spi")
relocate("io.opentelemetry.context", "io.opentelemetry.javaagent.shaded.io.opentelemetry.context")

// relocate OpenTelemetry API dependency
Expand Down
1 change: 1 addition & 0 deletions instrumentation/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ shadowJar {

// relocate OpenTelemetry API usage
relocate "io.opentelemetry.api", "io.opentelemetry.javaagent.shaded.io.opentelemetry.api"
relocate("io.opentelemetry.spi", "io.opentelemetry.javaagent.shaded.io.opentelemetry.spi")
relocate "io.opentelemetry.context", "io.opentelemetry.javaagent.shaded.io.opentelemetry.context"

}
7 changes: 7 additions & 0 deletions instrumentation/glassfish/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
plugins {
id "java"
}

dependencies {
compileOnly('org.glassfish.main.common:common-util:5.0')
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Copyright Splunk Inc.
*
* 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.
*/

package com.splunk.opentelemetry.middleware;

import static io.opentelemetry.javaagent.tooling.ClassLoaderMatcher.hasClassesNamed;
import static net.bytebuddy.matcher.ElementMatchers.isTypeInitializer;
import static net.bytebuddy.matcher.ElementMatchers.named;

import com.google.auto.service.AutoService;
import com.splunk.opentelemetry.javaagent.bootstrap.MiddlewareHolder;
import com.sun.appserv.server.util.Version;
import io.opentelemetry.javaagent.tooling.InstrumentationModule;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher;

@AutoService(InstrumentationModule.class)
public class GlassfishAttributesInstrumentationModule extends InstrumentationModule {

public GlassfishAttributesInstrumentationModule() {
super("glassfish");
}

@Override
public ElementMatcher.Junction<ClassLoader> classLoaderMatcher() {
return hasClassesNamed("com.sun.appserv.server.util.Version");
}

@Override
public List<TypeInstrumentation> typeInstrumentations() {
return Collections.singletonList(new Instrumentation());
}

public static class Instrumentation implements TypeInstrumentation {

@Override
public ElementMatcher<? super TypeDescription> typeMatcher() {
return named("com.sun.appserv.server.util.Version");
}

@Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
return Collections.singletonMap(
isTypeInitializer(),
GlassfishAttributesInstrumentationModule.class.getName()
+ "$MiddlewareInitializedAdvice");
}
}

@SuppressWarnings("unused")
public static class MiddlewareInitializedAdvice {
@Advice.OnMethodExit(suppress = Throwable.class)
public static void onExit() {
MiddlewareHolder.trySetName(Version.getProductName());
MiddlewareHolder.trySetVersion(Version.getVersionNumber());
}
}
}
2 changes: 1 addition & 1 deletion matrix/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ val versions: Map<String, String> by extra

dependencies {
implementation("javax.servlet:javax.servlet-api:3.0.1")
implementation("io.opentelemetry:opentelemetry-extension-auto-annotations:${versions["opentelemetry"]}")
implementation("io.opentelemetry:opentelemetry-extension-annotations:${versions["opentelemetry"]}")
}

fun dockerFileName(template: String) = template.replace("-dockerfile.template", ".dockerfile")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

package com.splunk.opentelemetry.appservers.javaee;

import io.opentelemetry.extension.auto.annotations.WithSpan;
import io.opentelemetry.extension.annotations.WithSpan;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
Expand Down
3 changes: 3 additions & 0 deletions matrix/src/main/webapp/WEB-INF/glassfish-web.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<glassfish-web-app>
<context-root>/</context-root>
</glassfish-web-app>
2 changes: 2 additions & 0 deletions matrix/src/payara-dockerfile.template
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
FROM payara/server-full:@version@

RUN rm ${PAYARA_DIR}/glassfish/modules/phonehome-bootstrap.jar

COPY app.war $DEPLOY_DIR
1 change: 1 addition & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ include("agent",
"custom",
"instrumentation",
"instrumentation:jetty",
"instrumentation:glassfish",
"instrumentation:tomcat",
"smoke-tests",
"matrix")
3 changes: 0 additions & 3 deletions smoke-tests/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@ dependencies {
}

tasks.test {
// TODO: remove once we will have the environment to push built images to.
dependsOn(":matrix:buildTestImages")

useJUnitPlatform()
reports {
junitXml.isOutputPerTestCase = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,11 @@ public abstract class AppServerTest extends SmokeTest {
* 1. Server span for the initial request to http://localhost:%d/greeting?url=http://localhost:8080/headers
* 2. Client http span to http://localhost:8080/headers
* 3. Server http span for http://localhost:8080/headers
* 4. Span created by the @WithSpan annotation.
* </code>
*/
protected void assertWebAppTrace(ExpectedServerAttributes serverAttributes)
throws IOException, InterruptedException {
String url =
String.format(
"http://localhost:%d/greeting?url=http://localhost:8080/headers",
target.getMappedPort(8080));
String url = String.format("http://localhost:%d/app/greeting", target.getMappedPort(8080));

Request request = new Request.Builder().get().url(url).build();
Response response = client.newCall(request).execute();
Expand Down Expand Up @@ -78,14 +74,11 @@ protected void assertWebAppTrace(ExpectedServerAttributes serverAttributes)
1, traces.countFilteredAttributes("http.url", url), "The span for the initial web request");
Assertions.assertEquals(
2,
traces.countFilteredAttributes("http.url", "http://localhost:8080/headers"),
traces.countFilteredAttributes("http.url", "http://localhost:8080/app/headers"),
"Client and server spans for the remote call");

Assertions.assertEquals(
1, traces.countSpansByName("GreetingServlet.withSpan"), "Span for the annotated method");

Assertions.assertEquals(
4,
3,
traces.countFilteredAttributes("otel.library.version", getCurrentAgentVersion()),
"Number of spans tagged with current otel library version");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright Splunk Inc.
*
* 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.
*/

package com.splunk.opentelemetry;

import static org.junit.jupiter.params.provider.Arguments.arguments;

import java.io.IOException;
import java.time.Duration;
import java.util.Map;
import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.testcontainers.containers.wait.strategy.Wait;
import org.testcontainers.containers.wait.strategy.WaitStrategy;

public class GlassFishSmokeTest extends AppServerTest {

public static final ExpectedServerAttributes PAYARA_SERVER_ATTRIBUTES =
new ExpectedServerAttributes(
"/this-is-definitely-not-there-but-there-should-be-a-trace-nevertheless",
"Payara Server",
"5.2020.6");

private static Stream<Arguments> supportedConfigurations() {
return Stream.of(
arguments(
"ghcr.io/open-telemetry/java-test-containers:payara-5.2020.6-jdk11-jdk11-20201207.405832649",
PAYARA_SERVER_ATTRIBUTES),
arguments(
"ghcr.io/open-telemetry/java-test-containers:payara-5.2020.6-jdk8-20201207.405832649",
PAYARA_SERVER_ATTRIBUTES));
}

@Override
protected Map<String, String> getExtraEnv() {
return Map.of("HZ_PHONE_HOME_ENABLED", "false");
}

@Override
protected WaitStrategy getWaitStrategy() {
return Wait.forLogMessage(".*app was successfully deployed.*", 1)
.withStartupTimeout(Duration.ofMinutes(15));
}

@ParameterizedTest
@MethodSource("supportedConfigurations")
void payaraSmokeTest(String imageName, ExpectedServerAttributes expectedServerAttributes)
throws IOException, InterruptedException {
startTarget(imageName);

assertServerHandler(expectedServerAttributes);
assertWebAppTrace(expectedServerAttributes);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,21 @@ public class JettySmokeTest extends AppServerTest {

private static Stream<Arguments> supportedConfigurations() {
return Stream.of(
arguments("splunk-jetty:9.4-jdk8", JETTY9_SERVER_ATTRIBUTES),
arguments("splunk-jetty:9.4-jdk11", JETTY9_SERVER_ATTRIBUTES),
arguments("splunk-jetty:9.4-jdk15", JETTY9_SERVER_ATTRIBUTES),
arguments("splunk-jetty:10.0.0.beta3-jdk11", JETTY10_SERVER_ATTRIBUTES),
arguments("splunk-jetty:10.0.0.beta3-jdk15", JETTY10_SERVER_ATTRIBUTES));
arguments(
"ghcr.io/open-telemetry/java-test-containers:jetty-9.4.35-jdk8-20201207.405832649",
JETTY9_SERVER_ATTRIBUTES),
arguments(
"ghcr.io/open-telemetry/java-test-containers:jetty-9.4.35-jdk11-20201207.405832649",
JETTY9_SERVER_ATTRIBUTES),
arguments(
"ghcr.io/open-telemetry/java-test-containers:jetty-9.4.35-jdk15-20201207.405832649",
JETTY9_SERVER_ATTRIBUTES),
arguments(
"ghcr.io/open-telemetry/java-test-containers:jetty-10.0.0.beta3-jdk11-20201207.405832649",
JETTY10_SERVER_ATTRIBUTES),
arguments(
"ghcr.io/open-telemetry/java-test-containers:jetty-10.0.0.beta3-jdk15-20201207.405832649",
JETTY10_SERVER_ATTRIBUTES));
}

@ParameterizedTest(name = "[{index}] {0}")
Expand Down
17 changes: 14 additions & 3 deletions smoke-tests/src/test/java/com/splunk/opentelemetry/SmokeTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
import org.testcontainers.containers.Network;
import org.testcontainers.containers.output.Slf4jLogConsumer;
import org.testcontainers.containers.wait.strategy.Wait;
import org.testcontainers.containers.wait.strategy.WaitStrategy;
import org.testcontainers.utility.DockerImageName;
import org.testcontainers.utility.MountableFile;

abstract class SmokeTest {
Expand All @@ -71,7 +73,8 @@ protected Map<String, String> getExtraEnv() {
static void setupSpec() {
backend =
new GenericContainer<>(
"open-telemetry-docker-dev.bintray.io/java/smoke-fake-backend:latest")
DockerImageName.parse(
"open-telemetry-docker-dev.bintray.io/java/smoke-fake-backend:latest"))
.withExposedPorts(8080)
.waitingFor(Wait.forHttp("/health").forPort(8080))
.withNetwork(network)
Expand All @@ -80,7 +83,7 @@ static void setupSpec() {
backend.start();

collector =
new GenericContainer<>("otel/opentelemetry-collector-dev:latest")
new GenericContainer<>(DockerImageName.parse("otel/opentelemetry-collector-dev:latest"))
.dependsOn(backend)
.withNetwork(network)
.withNetworkAliases("collector")
Expand All @@ -95,7 +98,7 @@ static void setupSpec() {

void startTarget(String targetImageName) {
target =
new GenericContainer<>(targetImageName)
new GenericContainer<>(DockerImageName.parse(targetImageName))
.withStartupTimeout(Duration.ofMinutes(5))
.withExposedPorts(8080)
.withNetwork(network)
Expand All @@ -107,9 +110,17 @@ void startTarget(String targetImageName) {
.withEnv("OTEL_BSP_SCHEDULE_DELAY", "10")
.withEnv("OTEL_EXPORTER_JAEGER_ENDPOINT", "http://collector:14268/api/traces")
.withEnv(getExtraEnv());
WaitStrategy waitStrategy = getWaitStrategy();
if (waitStrategy != null) {
target = target.waitingFor(waitStrategy);
}
target.start();
}

protected WaitStrategy getWaitStrategy() {
return null;
}

@AfterEach
void cleanup() throws IOException {
resetBackend();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,8 @@ public void springBootSmokeTestOnJDK(int jdk) throws IOException, InterruptedExc
Assertions.assertEquals(response.body().string(), "Hi!");
Assertions.assertEquals(1, traces.countSpansByName("/greeting"));
Assertions.assertEquals(1, traces.countSpansByName("WebController.greeting"));
Assertions.assertEquals(1, traces.countSpansByName("WebController.withSpan"));
Assertions.assertEquals(
3, traces.countFilteredAttributes("otel.library.version", currentAgentVersion));
2, traces.countFilteredAttributes("otel.library.version", currentAgentVersion));

stopTarget();
}
Expand Down
Loading

0 comments on commit 83e64a6

Please sign in to comment.