From d0d8bed69b299da8b74629c33450615f4ad721cc Mon Sep 17 00:00:00 2001 From: Sowmya Malayanur Date: Tue, 23 Sep 2025 13:18:15 -0700 Subject: [PATCH 1/4] spans using baggage to get parent's properties --- .../AzureActiveDirectoryWebViewClient.java | 51 +++++++++++++++---- .../java/opentelemetry/AttributeName.java | 10 ---- .../common/java/opentelemetry/SpanName.java | 4 +- 3 files changed, 43 insertions(+), 22 deletions(-) diff --git a/common/src/main/java/com/microsoft/identity/common/internal/ui/webview/AzureActiveDirectoryWebViewClient.java b/common/src/main/java/com/microsoft/identity/common/internal/ui/webview/AzureActiveDirectoryWebViewClient.java index 7cd7bf608b..520693f468 100644 --- a/common/src/main/java/com/microsoft/identity/common/internal/ui/webview/AzureActiveDirectoryWebViewClient.java +++ b/common/src/main/java/com/microsoft/identity/common/internal/ui/webview/AzureActiveDirectoryWebViewClient.java @@ -66,6 +66,7 @@ import com.microsoft.identity.common.java.flighting.CommonFlight; import com.microsoft.identity.common.java.flighting.CommonFlightsManager; import com.microsoft.identity.common.java.opentelemetry.AttributeName; +import com.microsoft.identity.common.java.opentelemetry.BaggageExtension; import com.microsoft.identity.common.java.opentelemetry.OTelUtility; import com.microsoft.identity.common.java.opentelemetry.SpanExtension; import com.microsoft.identity.common.java.opentelemetry.SpanName; @@ -86,7 +87,9 @@ import java.net.URISyntaxException; import java.net.URL; import java.security.Principal; +import java.util.Arrays; import java.util.HashMap; +import java.util.List; import java.util.Locale; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -102,6 +105,7 @@ import static com.microsoft.identity.common.java.exception.ClientException.UNKNOWN_ERROR; import static com.microsoft.identity.common.java.flighting.CommonFlight.ENABLE_PLAYSTORE_URL_LAUNCH; +import io.opentelemetry.api.baggage.Baggage; import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.api.trace.StatusCode; @@ -692,9 +696,7 @@ private boolean shouldLaunchCompanyPortal() { @VisibleForTesting protected void loadDeviceCaUrl(@NonNull final String originalUrl, @NonNull final WebView view) { final String methodTag = TAG + ":loadDeviceCaUrl"; - final SpanContext spanContext = getActivity() instanceof AuthorizationActivity ? ((AuthorizationActivity) getActivity()).getSpanContext() : null; - final Span span = spanContext != null ? - OTelUtility.createSpanFromParent(SpanName.ProcessWebCpRedirects.name(), spanContext) : OTelUtility.createSpan(SpanName.ProcessWebCpRedirects.name()); + final Span span = createWebCpFlowSpan(SpanName.ProcessWebCpRedirects.name()); try (final Scope scope = SpanExtension.makeCurrentSpan(span)) { if (isWebCpInWebviewFeatureEnabled(originalUrl)) { Logger.info(methodTag, "Loading device CA request in WebView."); @@ -739,7 +741,11 @@ protected boolean isWebCpInWebviewFeatureEnabled(@NonNull final String originalU final int waitForFlightsTimeOut = CommonFlightsManager.INSTANCE.getFlightsProvider().getIntValue(CommonFlight.WEB_CP_WAIT_TIMEOUT_FOR_FLIGHTS); final boolean isWebCpFlightEnabled = CommonFlightsManager.INSTANCE.getFlightsProviderForTenant(homeTenantId, waitForFlightsTimeOut).isFlightEnabled(CommonFlight.ENABLE_WEB_CP_IN_WEBVIEW); SpanExtension.current().setAttribute(AttributeName.web_cp_flight_get_time.name(), (System.currentTimeMillis() - webCpGetFlightStartTime)); +<<<<<<< HEAD +======= + SpanExtension.current().setAttribute(AttributeName.tenant_id.name(), homeTenantId); +>>>>>>> 37a33baf5 (spans using baggage to get parent's properties) if (isWebCpFlightEnabled) { // Directly enabled via flight rollout. Logger.info(methodTag, "WebCP in WebView feature is enabled."); @@ -767,11 +773,8 @@ private String getHomeTenantIdFromUrl(@NonNull final String url) { // This is a special case where the enrollment is not done in the WebView, but rather in the browser. private void processWebCpEnrollmentUrl(@NonNull final WebView view, @NonNull final String url) { final String methodTag = TAG + ":processWebCpEnrollmentUrl"; - final SpanContext spanContext = getActivity() instanceof AuthorizationActivity ? ((AuthorizationActivity) getActivity()).getSpanContext() : null; - final Span span = spanContext != null ? - OTelUtility.createSpanFromParent(SpanName.ProcessWebCpRedirects.name(), spanContext) : OTelUtility.createSpan(SpanName.ProcessWebCpRedirects.name()); + final Span span = createWebCpFlowSpan(SpanName.ProcessWebCpEnrollmentRedirect.name()); try (final Scope scope = SpanExtension.makeCurrentSpan(span)) { - span.setAttribute(AttributeName.is_webcp_enrollment_request.name(), true); view.stopLoading(); Logger.info(methodTag, "Loading WebCP enrollment url in browser."); // 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 +1067,7 @@ private void processNonceAndReAttachHeaders(@NonNull final WebView view, @NonNul private void processWebCpAuthorize(@NonNull final WebView view, @NonNull final String url) { final String methodTag = TAG + ":processWebCPAuthorize"; Logger.info(methodTag, "Processing WebCP authorize request."); - final SpanContext spanContext = getActivity() instanceof AuthorizationActivity ? ((AuthorizationActivity) getActivity()).getSpanContext() : null; - final Span span = spanContext != null ? - OTelUtility.createSpanFromParent(SpanName.ProcessWebCpRedirects.name(), spanContext) : OTelUtility.createSpan(SpanName.ProcessWebCpRedirects.name()); - span.setAttribute(AttributeName.is_webcp_authorize_request.name(), true); + final Span span = createWebCpFlowSpan(SpanName.ProcessWebCpAuthorizeUrlRedirect.name()); final ReAttachPrtHeaderHandler reAttachPrtHeaderHandler = new ReAttachPrtHeaderHandler(view, mRequestHeaders, span); reAttachPrtHeader(url, reAttachPrtHeaderHandler, view, methodTag, span); } @@ -1192,6 +1192,7 @@ public void finalizeBeforeSendingResult(@NonNull final RawAuthorizationResult re } /** +<<<<<<< HEAD * Extracts the broker app package name from the given URL. * Supports all known broker apps. Returns the first match found. * If no known broker app is found, logs a warning and returns an empty string. @@ -1209,4 +1210,32 @@ private String getBrokerAppPackageNameFromUrl(@NonNull final String url) { return ""; } +======= + * Create a span for webcp flow with parent span context if available. + * @param spanName Name of the span to be created. + * @return Created {@link Span} + */ + private Span createWebCpFlowSpan(@NonNull final String spanName) { + final SpanContext spanContext = getActivity() instanceof AuthorizationActivity ? ((AuthorizationActivity) getActivity()).getSpanContext() : null; + final Span span = spanContext != null ? + OTelUtility.createSpanFromParent(spanName, spanContext) : OTelUtility.createSpan(spanName); + // Populate some of parent span's attributes to current span. + final Context oTelContext = getActivity() instanceof AuthorizationActivity ? ((AuthorizationActivity) getActivity()).getOtelContext() : null; + if (oTelContext != null) { + final Baggage baggage = BaggageExtension.fromContext(oTelContext); + final List parentAttributeNames = Arrays.asList( + AttributeName.correlation_id, + AttributeName.tenant_id, + AttributeName.calling_package_name + ); + for (AttributeName attributeName : parentAttributeNames) { + String value = baggage.getEntryValue(attributeName.name()); + if (value != null) { + span.setAttribute(attributeName.name(), value); + } + } + } + return span; + } +>>>>>>> 37a33baf5 (spans using baggage to get parent's properties) } diff --git a/common4j/src/main/com/microsoft/identity/common/java/opentelemetry/AttributeName.java b/common4j/src/main/com/microsoft/identity/common/java/opentelemetry/AttributeName.java index 928f30e6d0..69780d9fca 100644 --- a/common4j/src/main/com/microsoft/identity/common/java/opentelemetry/AttributeName.java +++ b/common4j/src/main/com/microsoft/identity/common/java/opentelemetry/AttributeName.java @@ -413,16 +413,6 @@ public enum AttributeName { */ current_broker_package_name, - /** - * Records if the request is a webcp authorize request. - */ - is_webcp_authorize_request, - - /** - * Records if the request is a webcp enrollment request. - */ - is_webcp_enrollment_request, - /** * Records if the webcp is enabled in webview. */ diff --git a/common4j/src/main/com/microsoft/identity/common/java/opentelemetry/SpanName.java b/common4j/src/main/com/microsoft/identity/common/java/opentelemetry/SpanName.java index ddc8022b72..533dea4d85 100644 --- a/common4j/src/main/com/microsoft/identity/common/java/opentelemetry/SpanName.java +++ b/common4j/src/main/com/microsoft/identity/common/java/opentelemetry/SpanName.java @@ -69,5 +69,7 @@ public enum SpanName { ProcessWebCpRedirects, ProvisionResourceAccount, - ProcessWebsiteRequest + ProcessWebsiteRequest, + ProcessWebCpEnrollmentRedirect, + ProcessWebCpAuthorizeUrlRedirect } From dbe3b214ea8cf4947256780a3cd11eb53642c37f Mon Sep 17 00:00:00 2001 From: Sowmya Malayanur Date: Tue, 23 Sep 2025 13:19:43 -0700 Subject: [PATCH 2/4] added final --- .../internal/ui/webview/AzureActiveDirectoryWebViewClient.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/main/java/com/microsoft/identity/common/internal/ui/webview/AzureActiveDirectoryWebViewClient.java b/common/src/main/java/com/microsoft/identity/common/internal/ui/webview/AzureActiveDirectoryWebViewClient.java index 520693f468..3e205026a5 100644 --- a/common/src/main/java/com/microsoft/identity/common/internal/ui/webview/AzureActiveDirectoryWebViewClient.java +++ b/common/src/main/java/com/microsoft/identity/common/internal/ui/webview/AzureActiveDirectoryWebViewClient.java @@ -1229,7 +1229,7 @@ private Span createWebCpFlowSpan(@NonNull final String spanName) { AttributeName.calling_package_name ); for (AttributeName attributeName : parentAttributeNames) { - String value = baggage.getEntryValue(attributeName.name()); + final String value = baggage.getEntryValue(attributeName.name()); if (value != null) { span.setAttribute(attributeName.name(), value); } From 86dda0b05aaa98bbbc6e17a26e4d70f45d6bae9d Mon Sep 17 00:00:00 2001 From: Sowmya Malayanur Date: Tue, 23 Sep 2025 13:26:12 -0700 Subject: [PATCH 3/4] added final --- .../AzureActiveDirectoryWebViewClient.java | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/common/src/main/java/com/microsoft/identity/common/internal/ui/webview/AzureActiveDirectoryWebViewClient.java b/common/src/main/java/com/microsoft/identity/common/internal/ui/webview/AzureActiveDirectoryWebViewClient.java index 3e205026a5..48dfa2d496 100644 --- a/common/src/main/java/com/microsoft/identity/common/internal/ui/webview/AzureActiveDirectoryWebViewClient.java +++ b/common/src/main/java/com/microsoft/identity/common/internal/ui/webview/AzureActiveDirectoryWebViewClient.java @@ -696,7 +696,7 @@ private boolean shouldLaunchCompanyPortal() { @VisibleForTesting protected void loadDeviceCaUrl(@NonNull final String originalUrl, @NonNull final WebView view) { final String methodTag = TAG + ":loadDeviceCaUrl"; - final Span span = createWebCpFlowSpan(SpanName.ProcessWebCpRedirects.name()); + final Span span = createSpanWithAttributesFromParent(SpanName.ProcessWebCpRedirects.name()); try (final Scope scope = SpanExtension.makeCurrentSpan(span)) { if (isWebCpInWebviewFeatureEnabled(originalUrl)) { Logger.info(methodTag, "Loading device CA request in WebView."); @@ -741,11 +741,7 @@ protected boolean isWebCpInWebviewFeatureEnabled(@NonNull final String originalU final int waitForFlightsTimeOut = CommonFlightsManager.INSTANCE.getFlightsProvider().getIntValue(CommonFlight.WEB_CP_WAIT_TIMEOUT_FOR_FLIGHTS); final boolean isWebCpFlightEnabled = CommonFlightsManager.INSTANCE.getFlightsProviderForTenant(homeTenantId, waitForFlightsTimeOut).isFlightEnabled(CommonFlight.ENABLE_WEB_CP_IN_WEBVIEW); SpanExtension.current().setAttribute(AttributeName.web_cp_flight_get_time.name(), (System.currentTimeMillis() - webCpGetFlightStartTime)); -<<<<<<< HEAD - -======= SpanExtension.current().setAttribute(AttributeName.tenant_id.name(), homeTenantId); ->>>>>>> 37a33baf5 (spans using baggage to get parent's properties) if (isWebCpFlightEnabled) { // Directly enabled via flight rollout. Logger.info(methodTag, "WebCP in WebView feature is enabled."); @@ -773,7 +769,7 @@ private String getHomeTenantIdFromUrl(@NonNull final String url) { // This is a special case where the enrollment is not done in the WebView, but rather in the browser. private void processWebCpEnrollmentUrl(@NonNull final WebView view, @NonNull final String url) { final String methodTag = TAG + ":processWebCpEnrollmentUrl"; - final Span span = createWebCpFlowSpan(SpanName.ProcessWebCpEnrollmentRedirect.name()); + final Span span = createSpanWithAttributesFromParent(SpanName.ProcessWebCpEnrollmentRedirect.name()); try (final Scope scope = SpanExtension.makeCurrentSpan(span)) { view.stopLoading(); Logger.info(methodTag, "Loading WebCP enrollment url in browser."); @@ -1067,7 +1063,7 @@ private void processNonceAndReAttachHeaders(@NonNull final WebView view, @NonNul private void processWebCpAuthorize(@NonNull final WebView view, @NonNull final String url) { final String methodTag = TAG + ":processWebCPAuthorize"; Logger.info(methodTag, "Processing WebCP authorize request."); - final Span span = createWebCpFlowSpan(SpanName.ProcessWebCpAuthorizeUrlRedirect.name()); + final Span span = createSpanWithAttributesFromParent(SpanName.ProcessWebCpAuthorizeUrlRedirect.name()); final ReAttachPrtHeaderHandler reAttachPrtHeaderHandler = new ReAttachPrtHeaderHandler(view, mRequestHeaders, span); reAttachPrtHeader(url, reAttachPrtHeaderHandler, view, methodTag, span); } @@ -1192,7 +1188,6 @@ public void finalizeBeforeSendingResult(@NonNull final RawAuthorizationResult re } /** -<<<<<<< HEAD * Extracts the broker app package name from the given URL. * Supports all known broker apps. Returns the first match found. * If no known broker app is found, logs a warning and returns an empty string. @@ -1210,22 +1205,24 @@ private String getBrokerAppPackageNameFromUrl(@NonNull final String url) { return ""; } -======= - * Create a span for webcp flow with parent span context if available. + /** + * Create a span with parent span context if available. * @param spanName Name of the span to be created. * @return Created {@link Span} */ - private Span createWebCpFlowSpan(@NonNull final String spanName) { + private Span createSpanWithAttributesFromParent(@NonNull final String spanName) { final SpanContext spanContext = getActivity() instanceof AuthorizationActivity ? ((AuthorizationActivity) getActivity()).getSpanContext() : null; final Span span = spanContext != null ? OTelUtility.createSpanFromParent(spanName, spanContext) : OTelUtility.createSpan(spanName); - // Populate some of parent span's attributes to current span. + if (mUtid != null) { + span.setAttribute(AttributeName.tenant_id.name(), mUtid); + } + // Populate some of the parent span's attributes to current span. final Context oTelContext = getActivity() instanceof AuthorizationActivity ? ((AuthorizationActivity) getActivity()).getOtelContext() : null; if (oTelContext != null) { final Baggage baggage = BaggageExtension.fromContext(oTelContext); final List parentAttributeNames = Arrays.asList( AttributeName.correlation_id, - AttributeName.tenant_id, AttributeName.calling_package_name ); for (AttributeName attributeName : parentAttributeNames) { @@ -1237,5 +1234,4 @@ private Span createWebCpFlowSpan(@NonNull final String spanName) { } return span; } ->>>>>>> 37a33baf5 (spans using baggage to get parent's properties) } From fde86ebc7e3b0509d358cf48e42483353897dc9c Mon Sep 17 00:00:00 2001 From: Sowmya Malayanur Date: Sun, 28 Sep 2025 22:56:09 -0700 Subject: [PATCH 4/4] rebased --- .../ui/webview/AzureActiveDirectoryWebViewClient.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/common/src/main/java/com/microsoft/identity/common/internal/ui/webview/AzureActiveDirectoryWebViewClient.java b/common/src/main/java/com/microsoft/identity/common/internal/ui/webview/AzureActiveDirectoryWebViewClient.java index 48dfa2d496..be026b3e7e 100644 --- a/common/src/main/java/com/microsoft/identity/common/internal/ui/webview/AzureActiveDirectoryWebViewClient.java +++ b/common/src/main/java/com/microsoft/identity/common/internal/ui/webview/AzureActiveDirectoryWebViewClient.java @@ -583,9 +583,7 @@ private void processSwitchBrowserRequest(@NonNull final String url) { protected void processWebsiteRequest(@NonNull final WebView view, @NonNull final String url) { final String methodTag = TAG + ":processWebsiteRequest"; view.stopLoading(); - final SpanContext spanContext = getActivity() instanceof AuthorizationActivity ? ((AuthorizationActivity) getActivity()).getSpanContext() : null; - final Span span = spanContext != null ? - OTelUtility.createSpanFromParent(SpanName.ProcessWebsiteRequest.name(), spanContext) : OTelUtility.createSpan(SpanName.ProcessWebsiteRequest.name()); + final Span span = createSpanWithAttributesFromParent(SpanName.ProcessWebsiteRequest.name()); span.setAttribute(AttributeName.is_in_web_cp_flow.name(), mInWebCpFlow); try (final Scope scope = SpanExtension.makeCurrentSpan(span)) { if (isDeviceCaRequest(url)) {