Skip to content

Commit 819b295

Browse files
committed
Fix and properly test azure function integration
1 parent 8354103 commit 819b295

File tree

16 files changed

+315
-6
lines changed

16 files changed

+315
-6
lines changed

agent/agent-tooling/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ dependencies {
2424
implementation("com.azure:azure-monitor-opentelemetry-autoconfigure:1.0.0-beta.2")
2525
compileOnly("io.opentelemetry.javaagent:opentelemetry-javaagent-bootstrap")
2626
compileOnly("io.opentelemetry.javaagent:opentelemetry-javaagent-tooling")
27+
compileOnly("io.opentelemetry.javaagent:opentelemetry-javaagent-tooling-java9")
2728
compileOnly("io.opentelemetry.javaagent.instrumentation:opentelemetry-javaagent-servlet-common-bootstrap")
2829
testImplementation("io.opentelemetry.javaagent:opentelemetry-javaagent-tooling")
2930

agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/init/AzureFunctionsInitializer.java

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@
55

66
import com.azure.monitor.opentelemetry.autoconfigure.implementation.utils.Strings;
77
import com.microsoft.applicationinsights.agent.internal.diagnostics.DiagnosticsHelper;
8-
import io.opentelemetry.javaagent.bootstrap.ClassFileTransformerHolder;
98
import io.opentelemetry.javaagent.bootstrap.InstrumentationHolder;
9+
import io.opentelemetry.javaagent.bootstrap.LambdaTransformer;
10+
import io.opentelemetry.javaagent.bootstrap.LambdaTransformerHolder;
11+
import io.opentelemetry.javaagent.tooling.Java8LambdaTransformer;
12+
import io.opentelemetry.javaagent.tooling.Java9LambdaTransformer;
1013
import java.lang.instrument.ClassFileTransformer;
1114
import java.lang.instrument.Instrumentation;
1215
import javax.annotation.Nullable;
@@ -49,15 +52,38 @@ public void run() {
4952

5053
private static void disableBytecodeInstrumentation() {
5154
Instrumentation instrumentation = InstrumentationHolder.getInstrumentation();
52-
ClassFileTransformer transformer = ClassFileTransformerHolder.getClassFileTransformer();
53-
if (instrumentation == null || transformer == null) {
55+
LambdaTransformer transformer = LambdaTransformerHolder.getLambdaTransformer();
56+
ClassFileTransformer classFileTransformer = getDelegate(transformer);
57+
if (instrumentation == null || classFileTransformer == null) {
5458
return;
5559
}
56-
if (instrumentation.removeTransformer(transformer)) {
57-
ClassFileTransformerHolder.setClassFileTransformer(null);
60+
if (instrumentation.removeTransformer(classFileTransformer)) {
61+
LambdaTransformerHolder.setLambdaTransformer(null);
5862
}
5963
}
6064

65+
@Nullable
66+
private static ClassFileTransformer getDelegate(LambdaTransformer transformer) {
67+
if (transformer instanceof Java8LambdaTransformer) {
68+
try {
69+
return (ClassFileTransformer)
70+
Java8LambdaTransformer.class.getDeclaredField("delegate").get(transformer);
71+
} catch (ReflectiveOperationException e) {
72+
throw new IllegalStateException(e);
73+
}
74+
}
75+
if (transformer instanceof Java9LambdaTransformer) {
76+
try {
77+
return (ClassFileTransformer)
78+
Java9LambdaTransformer.class.getDeclaredField("delegate").get(transformer);
79+
} catch (ReflectiveOperationException e) {
80+
throw new IllegalStateException(e);
81+
}
82+
}
83+
throw new IllegalStateException(
84+
"Unexpected LambdaTransformer implementation: " + transformer.getClass());
85+
}
86+
6187
private void initialize() {
6288
RuntimeConfiguration runtimeConfig = runtimeConfigurator.getCurrentConfigCopy();
6389

settings.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ include(":smoke-tests:framework")
6161
hideFromDependabot(":smoke-tests:apps:ActuatorMetrics")
6262
hideFromDependabot(":smoke-tests:apps:AutoPerfCounters")
6363
hideFromDependabot(":smoke-tests:apps:AzureSdk")
64+
hideFromDependabot(":smoke-tests:apps:AzureFunctions")
6465
hideFromDependabot(":smoke-tests:apps:BrowserSdkLoader")
6566
hideFromDependabot(":smoke-tests:apps:Cassandra")
6667
hideFromDependabot(":smoke-tests:apps:ClassicSdkLog4j1Interop2x")
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
plugins {
2+
id("ai.smoke-test-jar")
3+
}
4+
5+
dependencies {
6+
implementation("org.springframework.boot:spring-boot-starter-web:2.5.12")
7+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
package com.microsoft.applicationinsights.smoketestapp;
5+
6+
import com.microsoft.azure.functions.worker.handler.FunctionEnvironmentReloadRequestHandler;
7+
import java.lang.reflect.Field;
8+
import java.util.Map;
9+
import org.springframework.boot.SpringApplication;
10+
import org.springframework.boot.autoconfigure.SpringBootApplication;
11+
12+
@SpringBootApplication
13+
public class SpringBootApp {
14+
15+
private static final String FAKE_BREEZE_INGESTION_ENDPOINT =
16+
"http://host.testcontainers.internal:6060/";
17+
18+
public static void main(String[] args) throws Exception {
19+
20+
setEnv("AzureWebJobsStorage", "dummy");
21+
setEnv(
22+
"APPLICATIONINSIGHTS_CONNECTION_STRING",
23+
"InstrumentationKey=00000000-0000-0000-0000-0FEEDDADBEEF;IngestionEndpoint="
24+
+ FAKE_BREEZE_INGESTION_ENDPOINT
25+
+ ";LiveEndpoint="
26+
+ FAKE_BREEZE_INGESTION_ENDPOINT);
27+
28+
new FunctionEnvironmentReloadRequestHandler().execute();
29+
30+
SpringApplication.run(SpringBootApp.class, args);
31+
}
32+
33+
public static void setEnv(String name, String value) throws Exception {
34+
Map<String, String> env = System.getenv();
35+
Class<?> cl = env.getClass();
36+
Field field = cl.getDeclaredField("m");
37+
field.setAccessible(true);
38+
@SuppressWarnings("unchecked")
39+
Map<String, String> writableEnv = (Map<String, String>) field.get(env);
40+
writableEnv.put(name, value);
41+
}
42+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
package com.microsoft.applicationinsights.smoketestapp;
5+
6+
import org.springframework.web.bind.annotation.GetMapping;
7+
import org.springframework.web.bind.annotation.RestController;
8+
9+
@RestController
10+
public class TestController {
11+
12+
@GetMapping("/")
13+
public String root() {
14+
return "OK";
15+
}
16+
17+
@GetMapping("/test")
18+
public String test() {
19+
return "OK!";
20+
}
21+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
package com.microsoft.azure.functions.rpc.messages;
5+
6+
public class InvocationRequest {
7+
8+
public RpcTraceContext getTraceContext() {
9+
throw new UnsupportedOperationException();
10+
}
11+
12+
public String getInvocationId() {
13+
throw new UnsupportedOperationException();
14+
}
15+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
package com.microsoft.azure.functions.rpc.messages;
5+
6+
import java.util.Map;
7+
8+
public class RpcTraceContext {
9+
10+
public Map<String, String> getAttributesMap() {
11+
throw new UnsupportedOperationException();
12+
}
13+
14+
public String getTraceParent() {
15+
throw new UnsupportedOperationException();
16+
}
17+
18+
public String getTraceState() {
19+
throw new UnsupportedOperationException();
20+
}
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
package com.microsoft.azure.functions.worker.handler;
5+
6+
public class FunctionEnvironmentReloadRequestHandler {
7+
8+
// calling this stub will trigger the azure functions initialization instrumentation
9+
public void execute() {}
10+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
package com.microsoft.azure.functions.worker.handler;
5+
6+
import com.microsoft.azure.functions.rpc.messages.InvocationRequest;
7+
8+
public class InvocationRequestHandler {
9+
10+
public void execute(InvocationRequest request) {}
11+
}

0 commit comments

Comments
 (0)