Skip to content

Commit

Permalink
Make 3.4 Classic SDK work with prior 3.x Agent versions (#2531)
Browse files Browse the repository at this point in the history
Resolves
#2522 (comment)

TODO add smoke tests
  • Loading branch information
trask authored Sep 23, 2022
1 parent 0449312 commit bb35191
Show file tree
Hide file tree
Showing 32 changed files with 1,261 additions and 49 deletions.
5 changes: 5 additions & 0 deletions buildSrc/src/main/kotlin/ai.smoke-test.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ afterEvaluate {
}

val agent by configurations.creating
val old3xAgent by configurations.creating

dependencies {
// FIXME (trask) copy-pasted from ai.java-conventions.gradle
Expand All @@ -70,6 +71,8 @@ dependencies {
smokeTestImplementation("org.assertj:assertj-core")

agent(project(":agent:agent", configuration = "shadow"))

old3xAgent("com.microsoft.azure:applicationinsights-agent:3.2.11")
}

tasks {
Expand All @@ -91,10 +94,12 @@ tasks {

val appFile = aiSmokeTest.testAppArtifactDir.file(aiSmokeTest.testAppArtifactFilename.get()).get()
val javaagentFile = agent.singleFile
val old3xJavaagentFile = old3xAgent.singleFile

// need to delay for project to configure the extension
systemProperty("ai.smoke-test.test-app-file", appFile)
systemProperty("ai.smoke-test.javaagent-file", javaagentFile)
systemProperty("ai.smoke-test.old-3x-javaagent-file", old3xJavaagentFile)

val smokeTestMatrix = findProperty("smokeTestMatrix") ?: System.getenv("CI") != null
systemProperty("ai.smoke-test.matrix", smokeTestMatrix)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,16 @@ public class TelemetryClient {

private final TelemetryContext context = new TelemetryContext();

// this is required for interop with versions of the Java agent prior to 3.4.0
@SuppressWarnings("UnusedVariable")
private final TelemetryConfiguration configuration = new TelemetryConfiguration();

// this is required for interop with versions of the Java agent prior to 3.4.0
@SuppressWarnings({"UnusedMethod", "MethodCanBeStatic"})
private boolean isDisabled() {
return false;
}

public TelemetryClient() {}

public TelemetryContext getContext() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.microsoft.applicationinsights;

// this class is required for interop with versions of the Java agent prior to 3.4.0
class TelemetryConfiguration {

// this method is required for interop with versions of the Java agent prior to 3.4.0
boolean isTrackingDisabled() {
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ public Throwable getThrowable() {
return throwable;
}

// this is required for interop with versions of the Java agent prior to 3.4.0
@Nullable
public Exception getException() {
return throwable instanceof Exception ? (Exception) throwable : null;
}

public void setException(Throwable throwable) {
setException(throwable, Integer.MAX_VALUE);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import com.microsoft.applicationinsights.extensibility.context.UserContext;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import javax.annotation.Nullable;

/**
* Represents a context for sending telemetry to the Application Insights service. The context holds
Expand Down Expand Up @@ -116,6 +117,12 @@ public void setConnectionString(String connectionString) {
this.connectionString = connectionString;
}

// this is required for interop with versions of the Java agent prior to 3.4.0
@Nullable
public String getInstrumentationKey() {
return null;
}

/** Gets a dictionary of application-defined property values. */
public ConcurrentMap<String, String> getProperties() {
return properties;
Expand Down
2 changes: 2 additions & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,11 @@ include ':smoke-tests:apps:AzureSdk'
include ':smoke-tests:apps:Cassandra'
include ':smoke-tests:apps:ClassicSdkWebInterop2x'
include ':smoke-tests:apps:ClassicSdkWebInterop3x'
include ':smoke-tests:apps:ClassicSdkWebInterop3xUsingOld3xAgent'
include ':smoke-tests:apps:ConnectionStringOverrides'
include ':smoke-tests:apps:CoreAndFilter2x'
include ':smoke-tests:apps:CoreAndFilter3x'
include ':smoke-tests:apps:CoreAndFilter3xUsingOld3xAgent'
include ':smoke-tests:apps:CustomDimensions'
include ':smoke-tests:apps:CustomInstrumentation'
include ':smoke-tests:apps:gRPC'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
plugins {
id("ai.smoke-test-war")
}

dependencies {
implementation(project(":classic-sdk:web"))
implementation("org.springframework.boot:spring-boot-starter-web:2.1.7.RELEASE") {
exclude("org.springframework.boot", "spring-boot-starter-tomcat")
}
// this dependency is needed to make wildfly happy
implementation("org.reactivestreams:reactive-streams:1.0.3")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.microsoft.applicationinsights.smoketestapp;

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

@SpringBootApplication
public class SpringBootApp extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder applicationBuilder) {
return applicationBuilder.sources(SpringBootApp.class);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.microsoft.applicationinsights.smoketestapp;

import com.microsoft.applicationinsights.telemetry.RequestTelemetry;
import com.microsoft.applicationinsights.web.internal.ThreadContext;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {

@GetMapping("/")
public String root() {
return "OK";
}

@GetMapping("/test")
public String test() {
RequestTelemetry requestTelemetry =
ThreadContext.getRequestTelemetryContext().getHttpRequestTelemetry();
requestTelemetry.getProperties().put("myattr1", "myvalue1");
requestTelemetry.getProperties().put("myattr2", "myvalue2");
requestTelemetry.getContext().getUser().setId("myuser");
requestTelemetry.getContext().getSession().setId("mysessionid");
requestTelemetry.getContext().getDevice().setOperatingSystem("mydeviceos");
requestTelemetry.getContext().getDevice().setOperatingSystemVersion("mydeviceosversion");
requestTelemetry.setName("myspanname");
requestTelemetry.setSource("mysource");
requestTelemetry.setSuccess(false);
return "OK!";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.microsoft.applicationinsights.smoketest;

import static com.microsoft.applicationinsights.smoketest.WarEnvironmentValue.TOMCAT_8_JAVA_11;
import static com.microsoft.applicationinsights.smoketest.WarEnvironmentValue.TOMCAT_8_JAVA_11_OPENJ9;
import static com.microsoft.applicationinsights.smoketest.WarEnvironmentValue.TOMCAT_8_JAVA_17;
import static com.microsoft.applicationinsights.smoketest.WarEnvironmentValue.TOMCAT_8_JAVA_18;
import static com.microsoft.applicationinsights.smoketest.WarEnvironmentValue.TOMCAT_8_JAVA_19;
import static com.microsoft.applicationinsights.smoketest.WarEnvironmentValue.TOMCAT_8_JAVA_8;
import static com.microsoft.applicationinsights.smoketest.WarEnvironmentValue.TOMCAT_8_JAVA_8_OPENJ9;
import static com.microsoft.applicationinsights.smoketest.WarEnvironmentValue.WILDFLY_13_JAVA_8;
import static com.microsoft.applicationinsights.smoketest.WarEnvironmentValue.WILDFLY_13_JAVA_8_OPENJ9;
import static org.assertj.core.api.Assertions.assertThat;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

@UseAgent
abstract class ClassicSdkWebInterop3xUsingOld3xAgentTest {

@RegisterExtension static final SmokeTestExtension testing = SmokeTestExtension.create();

@Test
@TargetUri("/test")
void doMostBasicTest() throws Exception {
Telemetry telemetry = testing.getTelemetry(0);

assertThat(telemetry.rd.getName()).isEqualTo("myspanname");
assertThat(telemetry.rd.getSource()).isEqualTo("mysource");
assertThat(telemetry.rdEnvelope.getTags()).containsEntry("ai.user.id", "myuser");
assertThat(telemetry.rdEnvelope.getTags()).containsEntry("ai.session.id", "mysessionid");
assertThat(telemetry.rdEnvelope.getTags()).containsEntry("ai.device.os", "mydeviceos");
assertThat(telemetry.rdEnvelope.getTags().get("ai.device.osVersion"))
.isEqualTo("mydeviceosversion");
assertThat(telemetry.rd.getProperties()).containsEntry("myattr1", "myvalue1");
assertThat(telemetry.rd.getProperties()).containsEntry("myattr2", "myvalue2");
assertThat(telemetry.rd.getProperties()).hasSize(3);
assertThat(telemetry.rd.getProperties())
.containsEntry("_MS.ProcessedByMetricExtractors", "True");

assertThat(telemetry.rd.getSuccess()).isFalse();
}

@Environment(TOMCAT_8_JAVA_8)
static class Tomcat8Java8Test extends ClassicSdkWebInterop3xUsingOld3xAgentTest {}

@Environment(TOMCAT_8_JAVA_8_OPENJ9)
static class Tomcat8Java8OpenJ9Test extends ClassicSdkWebInterop3xUsingOld3xAgentTest {}

@Environment(TOMCAT_8_JAVA_11)
static class Tomcat8Java11Test extends ClassicSdkWebInterop3xUsingOld3xAgentTest {}

@Environment(TOMCAT_8_JAVA_11_OPENJ9)
static class Tomcat8Java11OpenJ9Test extends ClassicSdkWebInterop3xUsingOld3xAgentTest {}

@Environment(TOMCAT_8_JAVA_17)
static class Tomcat8Java17Test extends ClassicSdkWebInterop3xUsingOld3xAgentTest {}

@Environment(TOMCAT_8_JAVA_18)
static class Tomcat8Java18Test extends ClassicSdkWebInterop3xUsingOld3xAgentTest {}

@Environment(TOMCAT_8_JAVA_19)
static class Tomcat8Java19Test extends ClassicSdkWebInterop3xUsingOld3xAgentTest {}

@Environment(WILDFLY_13_JAVA_8)
static class Wildfly13Java8Test extends ClassicSdkWebInterop3xUsingOld3xAgentTest {}

@Environment(WILDFLY_13_JAVA_8_OPENJ9)
static class Wildfly13Java8OpenJ9Test extends ClassicSdkWebInterop3xUsingOld3xAgentTest {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="warn">
<appender-ref ref="CONSOLE"/>
</root>
</configuration>
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,7 @@ private void validateSlowTest(int expectedDurationSeconds, String operationName)
assertThat(rdEnvelope.getTags()).containsEntry("ai.operation.name", operationName);
}

// old Application Insights version that do not support Java 11+
// old 2.x Application Insights version that do not support Java 11+

@Environment(TOMCAT_8_JAVA_8)
static class Tomcat8Java8Test extends CoreAndFilter2xTest {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,39 +236,6 @@ void trackMetric() throws Exception {
rd, rdEnvelope, mdEnvelope, "GET /CoreAndFilter3x/trackMetric");
}

@Test
@TargetUri("/trackMetricWithNamespace")
void trackMetricWithNamespace() throws Exception {
List<Envelope> rdList = testing.mockedIngestion.waitForItems("RequestData", 1);
List<Envelope> mdList = testing.mockedIngestion.waitForMetricItems("TimeToRespond", 1);

Envelope rdEnvelope = rdList.get(0);
Envelope mdEnvelope = mdList.get(0);

assertThat(rdEnvelope.getSampleRate()).isNull();
assertThat(mdEnvelope.getSampleRate()).isNull();

RequestData rd = (RequestData) ((Data<?>) rdEnvelope.getData()).getBaseData();
MetricData md = (MetricData) ((Data<?>) mdEnvelope.getData()).getBaseData();

List<DataPoint> metrics = md.getMetrics();
assertThat(metrics).hasSize(1);
DataPoint dp = metrics.get(0);

final double expectedValue = 111222333.0;
assertThat(dp.getValue()).isEqualTo(expectedValue);
assertThat(dp.getName()).isEqualTo("TimeToRespond");
assertThat(dp.getMetricNamespace()).isEqualTo("test");

assertThat(dp.getCount()).isNull();
assertThat(dp.getMin()).isNull();
assertThat(dp.getMax()).isNull();
assertThat(dp.getStdDev()).isNull();

SmokeTestExtension.assertParentChild(
rd, rdEnvelope, mdEnvelope, "GET /CoreAndFilter3x/trackMetricWithNamespace");
}

@Test
@TargetUri("/trackTrace")
void testTrackTrace() throws Exception {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
plugins {
id("ai.smoke-test-war")
}

dependencies {
implementation(project(":classic-sdk:core"))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.microsoft.applicationinsights.smoketestapp;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

// this is used by the test infra in order to know when it's ok to start running the tests
@WebServlet("")
public class HealthCheckServlet extends HttpServlet {

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.microsoft.applicationinsights.smoketestapp;

import java.util.concurrent.TimeUnit;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/requestSlow")
public class SimpleTestRequestSlowWithResponseTime extends HttpServlet {

protected void doGet(HttpServletRequest request, HttpServletResponse response) {
int sleepTime = 25;
String customSleepTime = request.getParameter("sleeptime");
if (customSleepTime != null) {
try {
sleepTime = Integer.parseInt(customSleepTime);
} catch (NumberFormatException e) {
System.err.printf("Invalid value for 'sleeptime': '%s'%n", customSleepTime);
}
}
try {
System.out.printf("Sleeping for %d seconds.%n", sleepTime);
TimeUnit.SECONDS.sleep(sleepTime);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.microsoft.applicationinsights.smoketestapp;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/autoExceptionWithFailedRequest")
public class SimpleThrowExceptionServlet extends HttpServlet {

protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException {
throw new ServletException("This is a auto thrown exception !");
}
}
Loading

0 comments on commit bb35191

Please sign in to comment.