Skip to content

Commit 934bc7b

Browse files
kryalamatrask
andauthored
Modify quick pulse code with authentication enabled (#1678)
* Temporarily add to this repo * Bump version to not conflict * Add azure-monitor-opentelemetry-exporter dependency * Remove tests * Remove create default telemetry configuration * Replace Channel with Rest Client * Remove internal.channel package * More * Update lockfiles * Core compiling * Core tests passing * Remove Exporter * Unit tests passing (still some ignored tho) * Remove more * Fix some FIXMEs * Fix more FIXMEs * Fix more FIXMEs * Bump version to 3.1.0 * Some fixes * Not using external exporter for now * Need to use BatchSpanProcessor now * Need to upstream: fix double slash in track url * Need to upstream: remove statusDescription property * DO NOT MERGE, TOO VERBOSE * Need to upstream: fix formatted duration * Optimization * More * Update gradle dependencies from compile to impl * Bring back old exporter * Update old exporter * More * Temporary? Remove NDJSON from fake ingestion * Use external exporter artifact after all * Fix wildfly * Fix dependency version and lock files * Fix metric telemetry and more * Fix LGTM issue * Rename TelemetryConfiguration to TelemetryClient * Set time * Remove system.out.println * Fix metrics * Fix sporadic failing test * Fix tests * Sporadic failing tests * Fix test * Ignore failing test * Ignore failing test * Fix ndjson * Revert "Temporary? Remove NDJSON from fake ingestion" This reverts commit c6d31c5. * quick pulse initial changes with httpipeline working code * add authentication related code * address comments, add clientsecret authenticationtype, add azure identity dependency * fix ndjson exception, add authpolicy to TelemetryClient * AadAuthentication to singleton * address comments, fix spotbug issues * fix smoke test, add lazyazurehttpclient, address comments * fix spotbug issues * address comments * Fix submodule * Fix submodule * fix cds profiler issue, address comments * Remove a couple of null checks * fix lgtm issue * spotbug workaround, ignore systemexit test for now * Update test/smoke/testApps/SystemExit/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/SpringBootAutoTest.java Co-authored-by: Trask Stalnaker <[email protected]>
1 parent 1ffad2b commit 934bc7b

File tree

27 files changed

+802
-306
lines changed

27 files changed

+802
-306
lines changed

agent/agent-tooling/gradle/dependency-locks/runtimeClasspath.lockfile

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ ch.qos.logback:logback-classic:1.2.3
77
ch.qos.logback:logback-core:1.2.3
88
com.azure:azure-core-http-netty:1.9.0
99
com.azure:azure-core:1.15.0
10+
com.azure:azure-identity:1.2.4
1011
com.azure:azure-monitor-opentelemetry-exporter:1.0.0-beta.4
1112
com.blogspot.mydailyjava:weak-lock-free:0.15
1213
com.fasterxml.jackson.core:jackson-annotations:2.12.2
@@ -17,7 +18,9 @@ com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.12.2
1718
com.fasterxml.jackson.module:jackson-module-jaxb-annotations:2.12.2
1819
com.fasterxml.jackson:jackson-bom:2.12.2
1920
com.fasterxml.woodstox:woodstox-core:6.2.4
21+
com.fasterxml:aalto-xml:1.0.0
2022
com.github.oshi:oshi-core:5.6.0
23+
com.github.stephenc.jcip:jcip-annotations:1.0-1
2124
com.google.auto.service:auto-service-annotations:1.0-rc7
2225
com.google.auto.service:auto-service:1.0-rc7
2326
com.google.auto:auto-common:0.10
@@ -28,6 +31,13 @@ com.google.guava:failureaccess:1.0.1
2831
com.google.guava:guava:30.1.1-jre
2932
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
3033
com.google.j2objc:j2objc-annotations:1.3
34+
com.madgag.spongycastle:core:1.54.0.0
35+
com.microsoft.azure:msal4j-persistence-extension:1.1.0
36+
com.microsoft.azure:msal4j:1.9.1
37+
com.nimbusds:content-type:2.1
38+
com.nimbusds:lang-tag:1.4.4
39+
com.nimbusds:nimbus-jose-jwt:8.18
40+
com.nimbusds:oauth2-oidc-sdk:8.23.1
3141
com.squareup.moshi:moshi:1.9.3
3242
com.squareup.okio:okio:1.16.0
3343
commons-codec:commons-codec:1.13
@@ -89,6 +99,8 @@ net.bytebuddy:byte-buddy-agent:1.10.18
8999
net.bytebuddy:byte-buddy:1.10.18
90100
net.java.dev.jna:jna-platform:5.7.0
91101
net.java.dev.jna:jna:5.7.0
102+
net.minidev:accessors-smart:1.2
103+
net.minidev:json-smart:2.3
92104
org.apache.commons:commons-lang3:3.11
93105
org.apache.commons:commons-text:1.9
94106
org.apache.httpcomponents:httpclient:4.5.13
@@ -97,7 +109,20 @@ org.checkerframework:checker-qual:3.12.0
97109
org.codehaus.woodstox:stax2-api:4.2.1
98110
org.jctools:jctools-core:3.3.0
99111
org.jetbrains.kotlin:kotlin-bom:1.4.21
112+
org.jetbrains:annotations:15.0
113+
org.linguafranca.pwdb:KeePassJava2-dom:2.1.4
114+
org.linguafranca.pwdb:KeePassJava2-jaxb:2.1.4
115+
org.linguafranca.pwdb:KeePassJava2-kdb:2.1.4
116+
org.linguafranca.pwdb:KeePassJava2-kdbx:2.1.4
117+
org.linguafranca.pwdb:KeePassJava2-simple:2.1.4
118+
org.linguafranca.pwdb:KeePassJava2:2.1.4
119+
org.linguafranca.pwdb:database:2.1.4
120+
org.ow2.asm:asm:5.0.4
100121
org.reactivestreams:reactive-streams:1.0.3
122+
org.simpleframework:simple-xml:2.7.1
101123
org.slf4j:jcl-over-slf4j:1.7.30
102124
org.slf4j:slf4j-api:1.7.30
103125
org.slf4j:slf4j-simple:1.7.30
126+
stax:stax-api:1.0.1
127+
stax:stax:1.2.0
128+
xpp3:xpp3:1.1.3.3

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

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
import com.microsoft.applicationinsights.agent.internal.wasbootstrap.configuration.RpConfiguration;
3636
import com.microsoft.applicationinsights.common.CommonUtils;
3737
import com.microsoft.applicationinsights.customExceptions.FriendlyException;
38+
import com.microsoft.applicationinsights.internal.authentication.AadAuthentication;
39+
import com.microsoft.applicationinsights.internal.channel.common.LazyAzureHttpClient;
3840
import com.microsoft.applicationinsights.internal.channel.common.LazyHttpClient;
3941
import com.microsoft.applicationinsights.internal.config.*;
4042
import com.microsoft.applicationinsights.internal.profiler.GcEventMonitor;
@@ -114,6 +116,11 @@ private static void start(Instrumentation instrumentation) {
114116
}
115117
// Function to validate user provided processor configuration
116118
validateProcessorConfiguration(config);
119+
config.preview.authentication.validate();
120+
//Inject authentication configuration
121+
Configuration.AadAuthentication authentication = config.preview.authentication;
122+
AadAuthentication.init(authentication.type, authentication.clientId, authentication.keePassDatabasePath,
123+
authentication.tenantId, authentication.clientSecret, authentication.authorityHost);
117124

118125
// FIXME do something with config
119126

@@ -127,13 +134,17 @@ private static void start(Instrumentation instrumentation) {
127134
// this is used to delay SSL initialization because SSL initialization triggers loading of
128135
// java.util.logging (starting with Java 8u231)
129136
// and JBoss/Wildfly need to install their own JUL manager before JUL is initialized
137+
LazyAzureHttpClient.safeToInitLatch = new CountDownLatch(1);
130138
LazyHttpClient.safeToInitLatch = new CountDownLatch(1);
131-
instrumentation.addTransformer(new JulListeningClassFileTransformer(LazyHttpClient.safeToInitLatch));
139+
instrumentation.addTransformer(new JulListeningClassFileTransformer(LazyAzureHttpClient.safeToInitLatch));
132140
}
133141

134142
if (config.proxy.host != null) {
143+
LazyAzureHttpClient.proxyHost= config.proxy.host;
144+
LazyAzureHttpClient.proxyPortNumber = config.proxy.port;
135145
LazyHttpClient.proxy = new HttpHost(config.proxy.host, config.proxy.port);
136146
}
147+
137148
AppIdSupplier appIdSupplier = AppIdSupplier.INSTANCE;
138149

139150
TelemetryClient telemetryClient = TelemetryClient.initActive(config.customDimensions, buildXmlConfiguration(config));

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

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,18 @@
2121

2222
package com.microsoft.applicationinsights.agent.internal;
2323

24-
import java.io.IOException;
2524
import java.net.URI;
2625
import java.util.concurrent.Executors;
2726
import java.util.concurrent.ScheduledExecutorService;
2827

28+
import com.azure.core.http.HttpMethod;
29+
import com.azure.core.http.HttpRequest;
30+
import com.azure.core.http.HttpResponse;
2931
import com.microsoft.applicationinsights.TelemetryClient;
30-
import com.microsoft.applicationinsights.internal.channel.common.LazyHttpClient;
32+
import com.microsoft.applicationinsights.internal.channel.common.LazyAzureHttpClient;
3133
import com.microsoft.applicationinsights.internal.util.ExceptionStats;
3234
import com.microsoft.applicationinsights.internal.util.ThreadPoolUtils;
3335
import io.opentelemetry.instrumentation.api.aisdk.AiAppId;
34-
import org.apache.http.HttpResponse;
35-
import org.apache.http.client.methods.HttpGet;
36-
import org.apache.http.util.EntityUtils;
3736
import org.slf4j.Logger;
3837
import org.slf4j.LoggerFactory;
3938

@@ -116,34 +115,30 @@ public void run() {
116115
return;
117116
}
118117

119-
HttpGet request = new HttpGet(uri);
120-
118+
HttpRequest request = new HttpRequest(HttpMethod.GET, uri.toString());
121119
HttpResponse response;
122120
try {
123-
response = LazyHttpClient.getInstance().execute(request);
121+
response = LazyAzureHttpClient.getInstance().send(request).block();
124122
} catch (Exception e) {
125123
// TODO handle Friendly SSL exception
126124
logger.debug(e.getMessage(), e);
127125
backOff("exception sending request to " + uri, e);
128126
return;
129127
}
130128

131-
String body;
132-
try {
133-
body = EntityUtils.toString(response.getEntity());
134-
} catch (IOException e) {
135-
logger.debug(e.getMessage(), e);
136-
backOff("exception reading response from " + uri, e);
137-
return;
129+
// this check is needed to make spotbugs happy
130+
if (response == null) {
131+
throw new IllegalStateException("response should never be null");
138132
}
139133

140-
int statusCode = response.getStatusLine().getStatusCode();
134+
String body = response.getBodyAsString().block();
135+
int statusCode = response.getStatusCode();
141136
if (statusCode != 200) {
142-
backOff("received " + statusCode + " " + response.getStatusLine().getReasonPhrase() + " from " + uri
137+
backOff("received " + statusCode + " from " + uri
143138
+ "\nfull response:\n" + body, null);
144139
return;
145140
}
146-
141+
147142
// check for case when breeze returns invalid value
148143
if (body == null || body.isEmpty()) {
149144
backOff("received empty body from " + uri, null);

agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/wasbootstrap/configuration/Configuration.java

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@
2424
import com.microsoft.applicationinsights.agent.bootstrap.diagnostics.DiagnosticsHelper;
2525
import com.microsoft.applicationinsights.agent.bootstrap.diagnostics.status.StatusFile;
2626
import com.microsoft.applicationinsights.customExceptions.FriendlyException;
27+
import com.microsoft.applicationinsights.internal.authentication.AuthenticationType;
2728
import com.microsoft.applicationinsights.internal.profiler.GcReportingLevel;
29+
import com.microsoft.applicationinsights.internal.system.SystemInformation;
2830

2931
import java.util.ArrayList;
3032
import java.util.HashMap;
@@ -77,6 +79,8 @@ public enum ProcessorType {
7779
}
7880
}
7981

82+
83+
8084
public static class Role {
8185

8286
public String name;
@@ -184,6 +188,7 @@ public static class PreviewConfiguration {
184188

185189
public ProfilerConfiguration profiler = new ProfilerConfiguration();
186190
public GcEventConfiguration gcEvents = new GcEventConfiguration();
191+
public AadAuthentication authentication = new AadAuthentication();
187192
}
188193

189194
public static class PreviewInstrumentation {
@@ -583,6 +588,62 @@ public static class GcEventConfiguration {
583588
public GcReportingLevel reportingLevel = GcReportingLevel.TENURED_ONLY;
584589
}
585590

591+
public static class AadAuthentication {
592+
public boolean enabled;
593+
public AuthenticationType type;
594+
public String clientId;
595+
public String keePassDatabasePath;
596+
public String tenantId;
597+
public String clientSecret;
598+
public String authorityHost;
599+
600+
public void validate() throws FriendlyException {
601+
if(!enabled) return;
602+
if(type == null) {
603+
throw new FriendlyException("AAD Authentication configuration is missing authentication \"type\".",
604+
"Please provide a valid authentication \"type\" under the \"authentication\" configuration. " +
605+
"Learn more about authentication configuration here: https://docs.microsoft.com/en-us/azure/azure-monitor/app/java-standalone-config");
606+
}
607+
608+
if(type == AuthenticationType.UAMI) {
609+
if(isEmpty(clientId)) {
610+
throw new FriendlyException("AAD Authentication configuration of type User Assigned Managed Identity is missing \"clientId\".",
611+
"Please provide a valid \"clientId\" under the \"authentication\" configuration. " +
612+
"Learn more about authentication configuration here: https://docs.microsoft.com/en-us/azure/azure-monitor/app/java-standalone-config");
613+
}
614+
}
615+
616+
// keePassDatabasePath is only required for Windows. No configuration needed for Linux / Mac.
617+
if(type == AuthenticationType.INTELLIJ && SystemInformation.INSTANCE.isWindows()) {
618+
if(isEmpty(keePassDatabasePath)) {
619+
throw new FriendlyException("AAD Authentication configuration of type Intellij is missing \"keePassDatabasePath\".",
620+
"Please provide a valid authentication \"keePassDatabasePath\" under the \"authentication\" configuration. This is only required for Windows. " +
621+
"Learn more about authentication configuration here: https://docs.microsoft.com/en-us/azure/azure-monitor/app/java-standalone-config");
622+
}
623+
}
624+
625+
if(type == AuthenticationType.CLIENTSECRET) {
626+
if (isEmpty(clientId)) {
627+
throw new FriendlyException("AAD Authentication configuration of type Client Secret Identity is missing \"clientId\".",
628+
"Please provide a valid \"clientId\" under the \"authentication\" configuration. " +
629+
"Learn more about authentication configuration here: https://docs.microsoft.com/en-us/azure/azure-monitor/app/java-standalone-config");
630+
}
631+
632+
if (isEmpty(tenantId)) {
633+
throw new FriendlyException("AAD Authentication configuration of type Client Secret Identity is missing \"tenantId\".",
634+
"Please provide a valid \"tenantId\" under the \"authentication\" configuration. " +
635+
"Learn more about authentication configuration here: https://docs.microsoft.com/en-us/azure/azure-monitor/app/java-standalone-config");
636+
}
637+
638+
if (isEmpty(clientSecret)) {
639+
throw new FriendlyException("AAD Authentication configuration of type Client Secret Identity is missing \"clientSecret\".",
640+
"Please provide a valid \"clientSecret\" under the \"authentication\" configuration. " +
641+
"Learn more about authentication configuration here: https://docs.microsoft.com/en-us/azure/azure-monitor/app/java-standalone-config");
642+
}
643+
}
644+
}
645+
}
646+
586647
private static boolean isEmpty(String str) {
587648
return str == null || str.trim().isEmpty();
588649
}

agent/agent-tooling/src/test/java/com/microsoft/applicationinsights/agent/internal/wasbootstrap/configuration/ConfigurationBuilderTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ public void testMalformedFaultyJson() throws IOException {
8181
}
8282
}
8383

84+
@Test
8485
public void testGetJsonEncodingExceptionMessage() {
8586
String pathNull = ConfigurationBuilder.getJsonEncodingExceptionMessage("file path/to/file",null);
8687
String pathEmpty = ConfigurationBuilder.getJsonEncodingExceptionMessage("file path/to/file","");

agent/agent-tooling/src/test/java/com/microsoft/applicationinsights/agent/internal/wasbootstrap/configuration/ConfigurationTest.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import com.microsoft.applicationinsights.agent.internal.wasbootstrap.configuration.Configuration.MatchType;
1616
import com.microsoft.applicationinsights.agent.internal.wasbootstrap.configuration.Configuration.ProcessorType;
1717
import com.microsoft.applicationinsights.agent.internal.wasbootstrap.configuration.ConfigurationBuilder.ConfigurationException;
18+
import com.microsoft.applicationinsights.internal.authentication.AuthenticationType;
1819
import com.squareup.moshi.JsonAdapter;
1920
import com.squareup.moshi.JsonDataException;
2021
import com.squareup.moshi.JsonReader;
@@ -191,6 +192,21 @@ public void shouldParseProcessorConfiguration() throws IOException {
191192
assertEquals("httpProtocol",attributesExtractConfig.actions.get(0).extractAttribute.groupNames.get(0));
192193
}
193194

195+
@Test
196+
public void shouldParseAuthenticationConfiguration() throws IOException {
197+
198+
Configuration configuration = loadConfiguration("applicationinsights_aadauth.json");
199+
PreviewConfiguration preview = configuration.preview;
200+
assertEquals("InstrumentationKey=00000000-0000-0000-0000-000000000000", configuration.connectionString);
201+
assertEquals(true, preview.authentication.enabled);
202+
assertEquals(AuthenticationType.SAMI, preview.authentication.type);
203+
assertEquals("123xyz", preview.authentication.clientId);
204+
assertEquals("tenant123", preview.authentication.tenantId);
205+
assertEquals("clientsecret123", preview.authentication.clientSecret);
206+
assertEquals("path/to/keePass", preview.authentication.keePassDatabasePath);
207+
assertEquals("https://test.com/microsoft/", preview.authentication.authorityHost);
208+
}
209+
194210
@Test
195211
public void shouldUseDefaults() throws IOException {
196212
envVars.set("WEBSITE_SITE_NAME", "Role Name From Website Env");
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"connectionString": "InstrumentationKey=00000000-0000-0000-0000-000000000000",
3+
"preview" : {
4+
"authentication" : {
5+
"enabled": true,
6+
"type": "SAMI",
7+
"clientId" : "123xyz",
8+
"keePassDatabasePath" : "path/to/keePass",
9+
"tenantId": "tenant123",
10+
"clientSecret": "clientsecret123",
11+
"authorityHost": "https://test.com/microsoft/"
12+
}
13+
}
14+
}

agent/exporter/gradle/dependency-locks/runtimeClasspath.lockfile

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# This file is expected to be part of source control.
44
com.azure:azure-core-http-netty:1.9.0
55
com.azure:azure-core:1.15.0
6+
com.azure:azure-identity:1.2.4
67
com.azure:azure-monitor-opentelemetry-exporter:1.0.0-beta.4
78
com.fasterxml.jackson.core:jackson-annotations:2.12.2
89
com.fasterxml.jackson.core:jackson-core:2.12.2
@@ -12,14 +13,23 @@ com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.12.2
1213
com.fasterxml.jackson.module:jackson-module-jaxb-annotations:2.12.2
1314
com.fasterxml.jackson:jackson-bom:2.12.2
1415
com.fasterxml.woodstox:woodstox-core:6.2.4
16+
com.fasterxml:aalto-xml:1.0.0
1517
com.github.oshi:oshi-core:5.6.0
18+
com.github.stephenc.jcip:jcip-annotations:1.0-1
1619
com.google.code.findbugs:jsr305:3.0.2
1720
com.google.code.gson:gson:2.8.2
1821
com.google.errorprone:error_prone_annotations:2.5.1
1922
com.google.guava:failureaccess:1.0.1
2023
com.google.guava:guava:30.1.1-jre
2124
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
2225
com.google.j2objc:j2objc-annotations:1.3
26+
com.madgag.spongycastle:core:1.54.0.0
27+
com.microsoft.azure:msal4j-persistence-extension:1.1.0
28+
com.microsoft.azure:msal4j:1.9.1
29+
com.nimbusds:content-type:2.1
30+
com.nimbusds:lang-tag:1.4.4
31+
com.nimbusds:nimbus-jose-jwt:8.18
32+
com.nimbusds:oauth2-oidc-sdk:8.23.1
2333
com.squareup.moshi:moshi:1.9.3
2434
com.squareup.okio:okio:1.16.0
2535
commons-codec:commons-codec:1.11
@@ -63,12 +73,27 @@ jakarta.activation:jakarta.activation-api:1.2.1
6373
jakarta.xml.bind:jakarta.xml.bind-api:2.3.2
6474
net.java.dev.jna:jna-platform:5.7.0
6575
net.java.dev.jna:jna:5.7.0
76+
net.minidev:accessors-smart:1.2
77+
net.minidev:json-smart:2.3
6678
org.apache.commons:commons-lang3:3.11
6779
org.apache.commons:commons-text:1.9
6880
org.apache.httpcomponents:httpclient:4.5.13
6981
org.apache.httpcomponents:httpcore:4.4.13
7082
org.checkerframework:checker-qual:3.8.0
7183
org.codehaus.woodstox:stax2-api:4.2.1
7284
org.jctools:jctools-core:3.3.0
85+
org.jetbrains:annotations:15.0
86+
org.linguafranca.pwdb:KeePassJava2-dom:2.1.4
87+
org.linguafranca.pwdb:KeePassJava2-jaxb:2.1.4
88+
org.linguafranca.pwdb:KeePassJava2-kdb:2.1.4
89+
org.linguafranca.pwdb:KeePassJava2-kdbx:2.1.4
90+
org.linguafranca.pwdb:KeePassJava2-simple:2.1.4
91+
org.linguafranca.pwdb:KeePassJava2:2.1.4
92+
org.linguafranca.pwdb:database:2.1.4
93+
org.ow2.asm:asm:5.0.4
7394
org.reactivestreams:reactive-streams:1.0.3
95+
org.simpleframework:simple-xml:2.7.1
7496
org.slf4j:slf4j-api:1.7.30
97+
stax:stax-api:1.0.1
98+
stax:stax:1.2.0
99+
xpp3:xpp3:1.1.3.3

0 commit comments

Comments
 (0)