Skip to content

Commit

Permalink
Modified UserAgentInterceptor and added TelemetryOptions. Modified un…
Browse files Browse the repository at this point in the history
…it tests to reflect this. (Azure#345)
  • Loading branch information
vcolin7 authored Sep 16, 2020
1 parent 459e128 commit a0e7e29
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
import android.content.Context;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.azure.android.core.http.HttpHeader;
import com.azure.android.core.http.options.TelemetryOptions;
import com.azure.android.core.provider.ApplicationInformationProvider;
import com.azure.android.core.provider.LocaleInformationProvider;
import com.azure.android.core.provider.PlatformInformationProvider;
Expand All @@ -29,11 +31,15 @@
public class UserAgentInterceptor implements Interceptor {
private static final String DEFAULT_USER_AGENT = "azsdk-android";

// From the design guidelines, the basic user agent header format is:
// azsdk-android-<sdk_name>/<sdk_version>
private static final String USER_AGENT_FORMAT = DEFAULT_USER_AGENT + "-%s/%s";

// From the design guidelines, the default user agent header format is:
// azsdk-android-<sdk_name>/<sdk_version> (<platform_info>; application_info>; <user_locale_info>
private static final String USER_AGENT_FORMAT = DEFAULT_USER_AGENT + "-%s/%s (%s; %s; %s)";
private static final String USER_AGENT_FORMAT_WITH_TELEMETRY = "%s (%s; %s; %s)";

// From the design guidelines, the application ID user agent header format is:
// From the design guidelines, the full user agent header format is:
// [<application_id>] azsdk-android-<client_lib>/<sdk_version> (<platform_info>; <application_info>;
// <user_locale_info>
private static final String USER_AGENT_FORMAT_WITH_APPLICATION_ID = "[%s] %s";
Expand All @@ -50,19 +56,19 @@ public class UserAgentInterceptor implements Interceptor {
// <user_language>_<user_region>
private static final String LOCALE_INFO_FORMAT = "%s_%s";

private final String userAgent;
private String userAgent;

/**
* Creates a {@link UserAgentInterceptor} with the {@code sdkName} and {@code sdkVersion} in the User-Agent
* header value.
*
* @param context The application's context.
* @param sdkName Name of the client library.
* @param sdkVersion Version of the client library.
* @param context The application's context.
* @param sdkName Name of the client library.
* @param sdkVersion Version of the client library.
*/
public UserAgentInterceptor(Context context,
String sdkName,
String sdkVersion) {
public UserAgentInterceptor(@NonNull Context context,
@Nullable String sdkName,
@Nullable String sdkVersion) {
this(null,
sdkName,
sdkVersion,
Expand All @@ -75,16 +81,16 @@ public UserAgentInterceptor(Context context,
* Creates a {@link UserAgentInterceptor} with the {@code sdkName} and {@code sdkVersion} in the User-Agent
* header value.
*
* @param context The application's context.
* @param applicationId User specified application ID.
* @param sdkName Name of the client library.
* @param sdkVersion Version of the client library.
* @param context The application's context.
* @param telemetryOptions Telemetry options for calls made by the pipeline.
* @param sdkName Name of the client library.
* @param sdkVersion Version of the client library.
*/
public UserAgentInterceptor(Context context,
String applicationId,
String sdkName,
String sdkVersion) {
this(applicationId,
public UserAgentInterceptor(@NonNull Context context,
@Nullable TelemetryOptions telemetryOptions,
@Nullable String sdkName,
@Nullable String sdkVersion) {
this(telemetryOptions,
sdkName,
sdkVersion,
PlatformInformationProvider.getDefault(),
Expand All @@ -96,46 +102,52 @@ public UserAgentInterceptor(Context context,
* Creates a {@link UserAgentInterceptor} with the {@code sdkName} and {@code sdkVersion} in the User-Agent
* header value.
*
* @param applicationId User specified application ID.
* @param telemetryOptions Telemetry options for calls made by the pipeline.
* @param sdkName Name of the client library.
* @param sdkVersion Version of the client library.
* @param platformInformationProvider Provider that contains platform information.
* @param applicationInformationProvider Provider that contains application information.
* @param localeInformationProvider Provider that contains system locale information.
*/
public UserAgentInterceptor(String applicationId,
String sdkName,
String sdkVersion,
PlatformInformationProvider platformInformationProvider,
ApplicationInformationProvider applicationInformationProvider,
LocaleInformationProvider localeInformationProvider) {
public UserAgentInterceptor(@Nullable TelemetryOptions telemetryOptions,
@Nullable String sdkName,
@Nullable String sdkVersion,
@Nullable PlatformInformationProvider platformInformationProvider,
@Nullable ApplicationInformationProvider applicationInformationProvider,
@Nullable LocaleInformationProvider localeInformationProvider) {
sdkName = sdkName == null ? "" : sdkName;
sdkVersion = sdkVersion == null ? "" : sdkVersion;

String userAgentBase = String.format(
userAgent = String.format(
USER_AGENT_FORMAT,
sdkName,
sdkVersion,
getPlatformInfo(platformInformationProvider),
getApplicationInfo(applicationInformationProvider),
getLocaleInfo(localeInformationProvider));
sdkVersion);

if (telemetryOptions != null) {
if (!telemetryOptions.isTelemetryDisabled()) {
userAgent = String.format(
USER_AGENT_FORMAT_WITH_TELEMETRY,
userAgent,
getPlatformInfo(platformInformationProvider),
getApplicationInfo(applicationInformationProvider),
getLocaleInfo(localeInformationProvider));
}

if (isNullOrEmpty(applicationId)) {
userAgent = userAgentBase;
} else {
// Based on the design guidelines, applicationId must not contain a space.
applicationId = applicationId.replaceAll("[\\n\\t ]", "");
String applicationId = telemetryOptions.getApplicationId();

// Based on the design guidelines, applicationId must not be more than 24 characters in length.
if (applicationId.length() > 24) {
applicationId = applicationId.substring(0, 24);
}
if (!isNullOrEmpty(applicationId)) {
// Based on the design guidelines, applicationId must not contain a space.
applicationId = applicationId.replaceAll("[\\n\\t ]", "");

// Based on the design guidelines, applicationId must not be more than 24 characters in length.
if (applicationId.length() > 24) {
applicationId = applicationId.substring(0, 24);
}

// Don't use the applicationId if it's empty after applying the validations above
if (applicationId.isEmpty()) {
userAgent = userAgentBase;
} else {
userAgent = String.format(USER_AGENT_FORMAT_WITH_APPLICATION_ID, applicationId, userAgentBase);
// Don't use the applicationId if it's empty after applying the validations above.
if (!applicationId.isEmpty()) {
userAgent = String.format(USER_AGENT_FORMAT_WITH_APPLICATION_ID, applicationId, userAgent);
}
}
}
}
Expand All @@ -148,7 +160,6 @@ public UserAgentInterceptor(String applicationId,
* User-Agent header is updated by prepending the value in this interceptor.
*
* @param chain Provide access to the request to apply the "User-Agent" header.
*
* @return Response from the next interceptor in the pipeline.
* @throws IOException If an IO error occurs while processing the request and response.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.android.core.http.options;

import androidx.annotation.Nullable;

import com.azure.android.core.http.ServiceClient;

/**
* Options for configuring telemetry sent by a {@link ServiceClient}.
*/
public class TelemetryOptions {
boolean telemetryDisabled;
@Nullable
String applicationId;

/**
* Creates an instance of {@link TelemetryOptions}.
*
* @param telemetryDisabled Whether platform information will be omitted from the user agent string sent by the
* {@link ServiceClient}.
* @param applicationId An optional user-specified application ID included in the user agent string sent by the
* {@link ServiceClient}.
*/
public TelemetryOptions(boolean telemetryDisabled, @Nullable String applicationId) {
this.telemetryDisabled = telemetryDisabled;
this.applicationId = applicationId;
}

/**
* Gets a flag indicating if telemetry is disabled for calls made with the {@link ServiceClient}.
*
* @return {@code true} if telemetry is disabled.
*/
public boolean isTelemetryDisabled() {
return telemetryDisabled;
}

/**
* Gets the application ID used in calls made by the {@link ServiceClient}.
*
* @return The application ID.
*/
@Nullable
public String getApplicationId() {
return applicationId;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

import android.content.Context;

import androidx.annotation.NonNull;

import com.azure.android.core.internal.provider.AndroidApplicationInformationProvider;

/**
Expand All @@ -17,7 +19,7 @@ public interface ApplicationInformationProvider {
* @param context Android {@link Context} object to extract data from.
* @return A default {@link ApplicationInformationProvider}.
*/
static ApplicationInformationProvider getDefault(Context context) {
static ApplicationInformationProvider getDefault(@NonNull Context context) {
return new AndroidApplicationInformationProvider(context);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

import android.content.Context;

import androidx.annotation.NonNull;

import com.azure.android.core.internal.provider.AndroidLocaleInformationProvider;

/**
Expand All @@ -17,7 +19,7 @@ public interface LocaleInformationProvider {
* @param context Android {@link Context} object to extract data from.
* @return A default {@link LocaleInformationProvider}.
*/
static LocaleInformationProvider getDefault(Context context) {
static LocaleInformationProvider getDefault(@NonNull Context context) {
return new AndroidLocaleInformationProvider(context);
}

Expand Down
Loading

0 comments on commit a0e7e29

Please sign in to comment.