Skip to content

Commit 6f0b749

Browse files
authored
Use baggage for spans, Fixes AB#3385536 (#2770)
Using baggage to get parent span's (AcquireTokenInteractive) correlationId, calling app package name and setting them on the child spans created during webcp redirects in webview. Why this needed? - We do not have correlationId set on webcp spans as of today. Although, we can check for the parent span and get correlationId from there, it is just an additional step. I want to avoid this. - We cannot directly set attributes to indicate that is webcp flow on the parent span (ATI) since the context passed to the activity is immutable. Recommended way is to create a child span and set attributes as needed on it. - We also cannot get parent span's attributes on child span directly using the context passed. Support for this was added by using baggage in this PR #2671. So, I am leveraging this. Related broker PR to remove the redundant attributes : AzureAD/ad-accounts-for-android#3230 Fixes [AB#3385536](https://identitydivision.visualstudio.com/fac9d424-53d2-45c0-91b5-ef6ba7a6bf26/_workitems/edit/3385536)
1 parent 7d28c9b commit 6f0b749

File tree

3 files changed

+41
-26
lines changed

3 files changed

+41
-26
lines changed

common/src/main/java/com/microsoft/identity/common/internal/ui/webview/AzureActiveDirectoryWebViewClient.java

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
import com.microsoft.identity.common.java.flighting.CommonFlight;
6767
import com.microsoft.identity.common.java.flighting.CommonFlightsManager;
6868
import com.microsoft.identity.common.java.opentelemetry.AttributeName;
69+
import com.microsoft.identity.common.java.opentelemetry.BaggageExtension;
6970
import com.microsoft.identity.common.java.opentelemetry.OTelUtility;
7071
import com.microsoft.identity.common.java.opentelemetry.SpanExtension;
7172
import com.microsoft.identity.common.java.opentelemetry.SpanName;
@@ -86,7 +87,9 @@
8687
import java.net.URISyntaxException;
8788
import java.net.URL;
8889
import java.security.Principal;
90+
import java.util.Arrays;
8991
import java.util.HashMap;
92+
import java.util.List;
9093
import java.util.Locale;
9194
import java.util.Map;
9295
import java.util.concurrent.TimeUnit;
@@ -102,6 +105,7 @@
102105
import static com.microsoft.identity.common.java.exception.ClientException.UNKNOWN_ERROR;
103106
import static com.microsoft.identity.common.java.flighting.CommonFlight.ENABLE_PLAYSTORE_URL_LAUNCH;
104107

108+
import io.opentelemetry.api.baggage.Baggage;
105109
import io.opentelemetry.api.trace.Span;
106110
import io.opentelemetry.api.trace.SpanContext;
107111
import io.opentelemetry.api.trace.StatusCode;
@@ -579,9 +583,7 @@ private void processSwitchBrowserRequest(@NonNull final String url) {
579583
protected void processWebsiteRequest(@NonNull final WebView view, @NonNull final String url) {
580584
final String methodTag = TAG + ":processWebsiteRequest";
581585
view.stopLoading();
582-
final SpanContext spanContext = getActivity() instanceof AuthorizationActivity ? ((AuthorizationActivity) getActivity()).getSpanContext() : null;
583-
final Span span = spanContext != null ?
584-
OTelUtility.createSpanFromParent(SpanName.ProcessWebsiteRequest.name(), spanContext) : OTelUtility.createSpan(SpanName.ProcessWebsiteRequest.name());
586+
final Span span = createSpanWithAttributesFromParent(SpanName.ProcessWebsiteRequest.name());
585587
span.setAttribute(AttributeName.is_in_web_cp_flow.name(), mInWebCpFlow);
586588
try (final Scope scope = SpanExtension.makeCurrentSpan(span)) {
587589
if (isDeviceCaRequest(url)) {
@@ -692,9 +694,7 @@ private boolean shouldLaunchCompanyPortal() {
692694
@VisibleForTesting
693695
protected void loadDeviceCaUrl(@NonNull final String originalUrl, @NonNull final WebView view) {
694696
final String methodTag = TAG + ":loadDeviceCaUrl";
695-
final SpanContext spanContext = getActivity() instanceof AuthorizationActivity ? ((AuthorizationActivity) getActivity()).getSpanContext() : null;
696-
final Span span = spanContext != null ?
697-
OTelUtility.createSpanFromParent(SpanName.ProcessWebCpRedirects.name(), spanContext) : OTelUtility.createSpan(SpanName.ProcessWebCpRedirects.name());
697+
final Span span = createSpanWithAttributesFromParent(SpanName.ProcessWebCpRedirects.name());
698698
try (final Scope scope = SpanExtension.makeCurrentSpan(span)) {
699699
if (isWebCpInWebviewFeatureEnabled(originalUrl)) {
700700
Logger.info(methodTag, "Loading device CA request in WebView.");
@@ -739,7 +739,7 @@ protected boolean isWebCpInWebviewFeatureEnabled(@NonNull final String originalU
739739
final int waitForFlightsTimeOut = CommonFlightsManager.INSTANCE.getFlightsProvider().getIntValue(CommonFlight.WEB_CP_WAIT_TIMEOUT_FOR_FLIGHTS);
740740
final boolean isWebCpFlightEnabled = CommonFlightsManager.INSTANCE.getFlightsProviderForTenant(homeTenantId, waitForFlightsTimeOut).isFlightEnabled(CommonFlight.ENABLE_WEB_CP_IN_WEBVIEW);
741741
SpanExtension.current().setAttribute(AttributeName.web_cp_flight_get_time.name(), (System.currentTimeMillis() - webCpGetFlightStartTime));
742-
742+
SpanExtension.current().setAttribute(AttributeName.tenant_id.name(), homeTenantId);
743743
if (isWebCpFlightEnabled) {
744744
// Directly enabled via flight rollout.
745745
Logger.info(methodTag, "WebCP in WebView feature is enabled.");
@@ -767,11 +767,8 @@ private String getHomeTenantIdFromUrl(@NonNull final String url) {
767767
// This is a special case where the enrollment is not done in the WebView, but rather in the browser.
768768
private void processWebCpEnrollmentUrl(@NonNull final WebView view, @NonNull final String url) {
769769
final String methodTag = TAG + ":processWebCpEnrollmentUrl";
770-
final SpanContext spanContext = getActivity() instanceof AuthorizationActivity ? ((AuthorizationActivity) getActivity()).getSpanContext() : null;
771-
final Span span = spanContext != null ?
772-
OTelUtility.createSpanFromParent(SpanName.ProcessWebCpRedirects.name(), spanContext) : OTelUtility.createSpan(SpanName.ProcessWebCpRedirects.name());
770+
final Span span = createSpanWithAttributesFromParent(SpanName.ProcessWebCpEnrollmentRedirect.name());
773771
try (final Scope scope = SpanExtension.makeCurrentSpan(span)) {
774-
span.setAttribute(AttributeName.is_webcp_enrollment_request.name(), true);
775772
view.stopLoading();
776773
Logger.info(methodTag, "Loading WebCP enrollment url in browser.");
777774
// This is a WebCP enrollment URL, so we need to open it in the browser (it does not work in WebView as google enrollment is enforced to be done in browser).
@@ -1064,10 +1061,7 @@ private void processNonceAndReAttachHeaders(@NonNull final WebView view, @NonNul
10641061
private void processWebCpAuthorize(@NonNull final WebView view, @NonNull final String url) {
10651062
final String methodTag = TAG + ":processWebCPAuthorize";
10661063
Logger.info(methodTag, "Processing WebCP authorize request.");
1067-
final SpanContext spanContext = getActivity() instanceof AuthorizationActivity ? ((AuthorizationActivity) getActivity()).getSpanContext() : null;
1068-
final Span span = spanContext != null ?
1069-
OTelUtility.createSpanFromParent(SpanName.ProcessWebCpRedirects.name(), spanContext) : OTelUtility.createSpan(SpanName.ProcessWebCpRedirects.name());
1070-
span.setAttribute(AttributeName.is_webcp_authorize_request.name(), true);
1064+
final Span span = createSpanWithAttributesFromParent(SpanName.ProcessWebCpAuthorizeUrlRedirect.name());
10711065
final ReAttachPrtHeaderHandler reAttachPrtHeaderHandler = new ReAttachPrtHeaderHandler(view, mRequestHeaders, span);
10721066
reAttachPrtHeader(url, reAttachPrtHeaderHandler, view, methodTag, span);
10731067
}
@@ -1209,4 +1203,33 @@ private String getBrokerAppPackageNameFromUrl(@NonNull final String url) {
12091203
return "";
12101204
}
12111205

1206+
/**
1207+
* Create a span with parent span context if available.
1208+
* @param spanName Name of the span to be created.
1209+
* @return Created {@link Span}
1210+
*/
1211+
private Span createSpanWithAttributesFromParent(@NonNull final String spanName) {
1212+
final SpanContext spanContext = getActivity() instanceof AuthorizationActivity ? ((AuthorizationActivity) getActivity()).getSpanContext() : null;
1213+
final Span span = spanContext != null ?
1214+
OTelUtility.createSpanFromParent(spanName, spanContext) : OTelUtility.createSpan(spanName);
1215+
if (mUtid != null) {
1216+
span.setAttribute(AttributeName.tenant_id.name(), mUtid);
1217+
}
1218+
// Populate some of the parent span's attributes to current span.
1219+
final Context oTelContext = getActivity() instanceof AuthorizationActivity ? ((AuthorizationActivity) getActivity()).getOtelContext() : null;
1220+
if (oTelContext != null) {
1221+
final Baggage baggage = BaggageExtension.fromContext(oTelContext);
1222+
final List<AttributeName> parentAttributeNames = Arrays.asList(
1223+
AttributeName.correlation_id,
1224+
AttributeName.calling_package_name
1225+
);
1226+
for (AttributeName attributeName : parentAttributeNames) {
1227+
final String value = baggage.getEntryValue(attributeName.name());
1228+
if (value != null) {
1229+
span.setAttribute(attributeName.name(), value);
1230+
}
1231+
}
1232+
}
1233+
return span;
1234+
}
12121235
}

common4j/src/main/com/microsoft/identity/common/java/opentelemetry/AttributeName.java

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -413,16 +413,6 @@ public enum AttributeName {
413413
*/
414414
current_broker_package_name,
415415

416-
/**
417-
* Records if the request is a webcp authorize request.
418-
*/
419-
is_webcp_authorize_request,
420-
421-
/**
422-
* Records if the request is a webcp enrollment request.
423-
*/
424-
is_webcp_enrollment_request,
425-
426416
/**
427417
* Records if the webcp is enabled in webview.
428418
*/

common4j/src/main/com/microsoft/identity/common/java/opentelemetry/SpanName.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,5 +69,7 @@ public enum SpanName {
6969
ProcessWebCpRedirects,
7070

7171
ProvisionResourceAccount,
72-
ProcessWebsiteRequest
72+
ProcessWebsiteRequest,
73+
ProcessWebCpEnrollmentRedirect,
74+
ProcessWebCpAuthorizeUrlRedirect
7375
}

0 commit comments

Comments
 (0)