2727import com .microsoft .identity .common .java .opentelemetry .SpanExtension ;
2828import com .microsoft .identity .common .java .util .StringUtil ;
2929
30- import org .json .JSONObject ;
31-
3230import edu .umd .cs .findbugs .annotations .Nullable ;
31+ import io .opentelemetry .api .trace .Span ;
3332import lombok .Getter ;
3433import lombok .Setter ;
3534import lombok .experimental .Accessors ;
3635
3736/**
38- * Model representing the x-ms-clientdata server telemetry header (from /token responses)
39- * and the clientdata query parameter (from /authorize redirect URLs).
37+ * Model representing server telemetry data from the x-ms-clientdata response header
38+ * (/token responses) and the clientdata query parameter (/authorize redirect URLs).
39+ * Both use a pipe-delimited format: account_type|error|sub_error|caller_data_boundary|cloud_instance.
4040 * Contains server-side error codes, account type, cloud instance, and data boundary info.
4141 */
4242@ Getter
@@ -49,21 +49,6 @@ public class ClientDataInfo {
4949 /** Maximum length for any individual field when emitting to a span. */
5050 private static final int MAX_FIELD_LENGTH = 256 ;
5151
52- /** JSON key for server error code. */
53- private static final String JSON_KEY_ERROR = "Error" ;
54-
55- /** JSON key for server sub-error code. */
56- private static final String JSON_KEY_SUB_ERROR = "SubError" ;
57-
58- /** JSON key for account type. */
59- private static final String JSON_KEY_ACCOUNT_TYPE = "AccountType" ;
60-
61- /** JSON key for cloud instance. */
62- private static final String JSON_KEY_CLOUD_INSTANCE = "cloud_instance" ;
63-
64- /** JSON key for caller data boundary. */
65- private static final String JSON_KEY_CALLER_DATA_BOUNDARY = "caller_data_boundary" ;
66-
6752 /** Account type value for MSA accounts. */
6853 private static final String ACCOUNT_TYPE_MSA_RAW = "m" ;
6954
@@ -93,35 +78,6 @@ public class ClientDataInfo {
9378 private String mCloudInstance ;
9479 private String mCallerDataBoundary ;
9580
96- /**
97- * Parses a URL-encoded JSON x-ms-clientdata value.
98- * Keys: Error, SubError, AccountType, cloud_instance, caller_data_boundary.
99- *
100- * @param urlEncodedJson URL-encoded JSON string, may be null.
101- * @return parsed {@link ClientDataInfo}, or null on failure/empty input.
102- */
103- @ Nullable
104- public static ClientDataInfo fromJson (@ Nullable final String urlEncodedJson ) {
105- if (StringUtil .isNullOrEmpty (urlEncodedJson )) {
106- return null ;
107- }
108- try {
109- final String decoded = StringUtil .urlFormDecode (urlEncodedJson );
110- final JSONObject json = new JSONObject (decoded );
111-
112- final ClientDataInfo info = new ClientDataInfo ();
113- info .mError = optString (json , JSON_KEY_ERROR );
114- info .mSubError = optString (json , JSON_KEY_SUB_ERROR );
115- info .mAccountType = optString (json , JSON_KEY_ACCOUNT_TYPE );
116- info .mCloudInstance = optString (json , JSON_KEY_CLOUD_INSTANCE );
117- info .mCallerDataBoundary = optString (json , JSON_KEY_CALLER_DATA_BOUNDARY );
118- return info ;
119- } catch (final Exception e ) {
120- Logger .warn (TAG , "Failed to parse x-ms-clientdata JSON: " + e .getMessage ());
121- return null ;
122- }
123- }
124-
12581 /**
12682 * Parses an already-decoded pipe-delimited clientdata query parameter value.
12783 * The caller is responsible for URL-decoding before passing (e.g. values from
@@ -167,27 +123,23 @@ public static ClientDataInfo fromPipeDelimited(@Nullable final String decodedVal
167123 * Each field is truncated to {@value #MAX_FIELD_LENGTH} characters.
168124 */
169125 public void emitToSpan () {
126+ final Span span = SpanExtension .current ();
170127 if (mError != null ) {
171- SpanExtension .current ().setAttribute (
172- AttributeName .server_error .name (), truncate (mError ));
128+ span .setAttribute (AttributeName .server_error .name (), truncate (mError ));
173129 }
174130 if (mSubError != null ) {
175- SpanExtension .current ().setAttribute (
176- AttributeName .server_sub_error .name (), truncate (mSubError ));
131+ span .setAttribute (AttributeName .server_sub_error .name (), truncate (mSubError ));
177132 }
178133 if (mAccountType != null ) {
179134 // account_type is an existing AttributeName; reuse it (m -> MSA, e -> AAD).
180135 final String mappedAccountType = mapAccountType (mAccountType );
181- SpanExtension .current ().setAttribute (
182- AttributeName .account_type .name (), truncate (mappedAccountType ));
136+ span .setAttribute (AttributeName .account_type .name (), truncate (mappedAccountType ));
183137 }
184138 if (mCloudInstance != null ) {
185- SpanExtension .current ().setAttribute (
186- AttributeName .server_cloud_instance .name (), truncate (mCloudInstance ));
139+ span .setAttribute (AttributeName .server_cloud_instance .name (), truncate (mCloudInstance ));
187140 }
188141 if (mCallerDataBoundary != null ) {
189- SpanExtension .current ().setAttribute (
190- AttributeName .server_caller_data_boundary .name (), truncate (mCallerDataBoundary ));
142+ span .setAttribute (AttributeName .server_caller_data_boundary .name (), truncate (mCallerDataBoundary ));
191143 }
192144 }
193145
@@ -208,15 +160,6 @@ private static String truncate(final String value) {
208160 return value .substring (0 , MAX_FIELD_LENGTH );
209161 }
210162
211- @ Nullable
212- private static String optString (final JSONObject json , final String key ) {
213- if (json .isNull (key )) {
214- return null ;
215- }
216- final String value = json .optString (key , null );
217- return StringUtil .isNullOrEmpty (value ) ? null : value ;
218- }
219-
220163 @ Nullable
221164 private static String emptyToNull (final String value ) {
222165 return StringUtil .isNullOrEmpty (value ) ? null : value ;
0 commit comments