diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java index c58a71c8b7ef..1be1f16115ad 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java @@ -40,10 +40,14 @@ import java.lang.reflect.Method; import java.net.HttpURLConnection; import java.net.URL; +import java.util.Enumeration; import java.util.Locale; import java.util.Objects; import java.util.ServiceLoader; import java.util.Set; +import java.util.jar.Attributes; +import java.util.jar.JarFile; +import java.util.jar.Manifest; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -56,6 +60,11 @@ public abstract class ServiceOptions< private static final String DEFAULT_HOST = "https://www.googleapis.com"; private static final long serialVersionUID = 1203687993961393350L; private static final String PROJECT_ENV_NAME = "GCLOUD_PROJECT"; + private static final String MANIFEST_ARTIFACT_ID_KEY = "artifactId"; + private static final String MANIFEST_VERSION_KEY = "Implementation-Version"; + private static final String ARTIFACT_ID = "gcloud-java-core"; + private static final String APPLICATION_BASE_NAME = "gcloud-java"; + private static final String APPLICATION_NAME = getApplicationName(); private final String projectId; private final String host; @@ -522,6 +531,13 @@ public Clock clock() { return clock; } + /** + * Returns the application's name as a string in the format {@code gcloud-java/[version]}. + */ + public String applicationName() { + return APPLICATION_NAME; + } + protected int baseHashCode() { return Objects.hash(projectId, host, httpTransportFactoryClassName, authCredentialsState, retryParams, serviceFactoryClassName, serviceRpcFactoryClassName, connectTimeout, @@ -568,4 +584,23 @@ private static T newInstance(String className) throws IOException, ClassNotF private static T getFromServiceLoader(Class clazz, T defaultInstance) { return Iterables.getFirst(ServiceLoader.load(clazz), defaultInstance); } + + private static String getApplicationName() { + String version = null; + try { + Enumeration resources = + ServiceOptions.class.getClassLoader().getResources(JarFile.MANIFEST_NAME); + while (resources.hasMoreElements() && version == null) { + Manifest manifest = new Manifest(resources.nextElement().openStream()); + Attributes manifestAttributes = manifest.getMainAttributes(); + String artifactId = manifestAttributes.getValue(MANIFEST_ARTIFACT_ID_KEY); + if (artifactId != null && artifactId.equals(ARTIFACT_ID)) { + version = manifestAttributes.getValue(MANIFEST_VERSION_KEY); + } + } + } catch (IOException e) { + // ignore + } + return version != null ? APPLICATION_BASE_NAME + "/" + version : APPLICATION_BASE_NAME; + } } diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/spi/DefaultStorageRpc.java b/gcloud-java-storage/src/main/java/com/google/gcloud/spi/DefaultStorageRpc.java index 90f2c98ad4b8..349cfbf771cb 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/spi/DefaultStorageRpc.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/spi/DefaultStorageRpc.java @@ -85,7 +85,7 @@ public DefaultStorageRpc(StorageOptions options) { this.options = options; storage = new Storage.Builder(transport, new JacksonFactory(), initializer) .setRootUrl(options.host()) - .setApplicationName("gcloud-java") + .setApplicationName(options.applicationName()) .build(); }