From 0397cc3dc43bfd7bf35a6267cda4bad1bc041ae8 Mon Sep 17 00:00:00 2001 From: Lawrence Qiu Date: Fri, 15 Dec 2023 17:47:27 -0500 Subject: [PATCH 01/21] feat: Add Java-Core Universe Domain changes --- .../java/com/google/cloud/BaseService.java | 25 ++++++++-- .../java/com/google/cloud/ServiceOptions.java | 48 +++++++++++++++++++ 2 files changed, 68 insertions(+), 5 deletions(-) diff --git a/java-core/google-cloud-core/src/main/java/com/google/cloud/BaseService.java b/java-core/google-cloud-core/src/main/java/com/google/cloud/BaseService.java index 781f29b421..c3901c1eab 100644 --- a/java-core/google-cloud-core/src/main/java/com/google/cloud/BaseService.java +++ b/java-core/google-cloud-core/src/main/java/com/google/cloud/BaseService.java @@ -17,7 +17,10 @@ package com.google.cloud; import com.google.api.core.InternalApi; +import com.google.auth.Credentials; +import com.google.auth.Retryable; import com.google.cloud.ExceptionHandler.Interceptor; +import java.io.IOException; /** * Base class for service objects. @@ -39,13 +42,15 @@ public RetryResult afterEval(Exception exception, RetryResult retryResult) { @Override public RetryResult beforeEval(Exception exception) { + boolean retryable = false; if (exception instanceof BaseServiceException) { - boolean retriable = ((BaseServiceException) exception).isRetryable(); - return retriable - ? Interceptor.RetryResult.RETRY - : Interceptor.RetryResult.CONTINUE_EVALUATION; + retryable = ((BaseServiceException) exception).isRetryable(); + } else if (exception instanceof Retryable) { + retryable = ((Retryable) exception).isRetryable(); } - return Interceptor.RetryResult.CONTINUE_EVALUATION; + return retryable + ? Interceptor.RetryResult.RETRY + : Interceptor.RetryResult.CONTINUE_EVALUATION; } }; public static final ExceptionHandler EXCEPTION_HANDLER = @@ -65,4 +70,14 @@ protected BaseService(OptionsT options) { public OptionsT getOptions() { return options; } + + public boolean isValidUniverseDomain() throws IOException { + Credentials credentials = getOptions().getCredentials(); + String universeDomain = getOptions().getUniverseDomain(); + if (universeDomain == null) { + universeDomain = ServiceOptions.GOOGLE_DEFAULT_UNIVERSE; + } + return true; + // return credentials.getUniverseDomain() != universeDomain; + } } diff --git a/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java b/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java index 231b9040c9..784159c558 100644 --- a/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java +++ b/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java @@ -46,6 +46,7 @@ import com.google.auth.oauth2.ServiceAccountCredentials; import com.google.cloud.spi.ServiceRpcFactory; import com.google.common.base.Preconditions; +import com.google.common.base.Strings; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; @@ -81,10 +82,12 @@ public abstract class ServiceOptions< implements Serializable { public static final String CREDENTIAL_ENV_NAME = "GOOGLE_APPLICATION_CREDENTIALS"; + public static final String GOOGLE_DEFAULT_UNIVERSE = "googleapis.com"; private static final String DEFAULT_HOST = "https://www.googleapis.com"; private static final String LEGACY_PROJECT_ENV_NAME = "GCLOUD_PROJECT"; private static final String PROJECT_ENV_NAME = "GOOGLE_CLOUD_PROJECT"; + private static final String ENDPOINT_TEMPLATE = "SERVICE_NAME.UNIVERSE_DOMAIN:443"; private static final RetrySettings DEFAULT_RETRY_SETTINGS = getDefaultRetrySettingsBuilder().build(); @@ -95,6 +98,7 @@ public abstract class ServiceOptions< protected final String clientLibToken; private final String projectId; + private final String universeDomain; private final String host; private final RetrySettings retrySettings; private final String serviceRpcFactoryClassName; @@ -125,6 +129,7 @@ public abstract static class Builder< private final ImmutableSet allowedClientLibTokens = ImmutableSet.of(ServiceOptions.getGoogApiClientLibName()); private String projectId; + private String universeDomain; private String host; protected Credentials credentials; private RetrySettings retrySettings; @@ -142,6 +147,7 @@ protected Builder() {} @InternalApi("This class should only be extended within google-cloud-java") protected Builder(ServiceOptions options) { projectId = options.projectId; + universeDomain = options.universeDomain; host = options.host; credentials = options.credentials; retrySettings = options.retrySettings; @@ -199,6 +205,16 @@ public B setHost(String host) { return self(); } + /** + * Sets the Universe Domain. + * + * @return the builder + */ + public B setUniverseDomain(String universeDomain) { + this.universeDomain = universeDomain; + return self(); + } + /** * Sets the service authentication credentials. If no credentials are set, {@link * GoogleCredentials#getApplicationDefault()} will be used to attempt getting credentials from @@ -306,6 +322,7 @@ protected ServiceOptions( "A project ID is required for this service but could not be determined from the builder " + "or the environment. Please set a project ID using the builder."); } + universeDomain = builder.universeDomain; host = firstNonNull(builder.host, getDefaultHost()); credentials = builder.credentials != null ? builder.credentials : defaultCredentials(); retrySettings = firstNonNull(builder.retrySettings, getDefaultRetrySettings()); @@ -582,6 +599,11 @@ public String getProjectId() { return projectId; } + /** Returns the Universe Domain */ + public String getUniverseDomain() { + return universeDomain; + } + /** Returns the service host. */ public String getHost() { return host; @@ -767,4 +789,30 @@ public String getClientLibToken() { public String getQuotaProjectId() { return quotaProjectId; } + + public String getResolvedEndpoint(String serviceName) { + if (universeDomain == null) { + return formatTemplate(serviceName, GOOGLE_DEFAULT_UNIVERSE); + } else if (Strings.isNullOrEmpty(universeDomain)) { + throw new RuntimeException("Universe Domain cannot be empty"); + } else { + if (host == null) { + return formatTemplate(serviceName, getUniverseDomain()); + } + return host; + } + } + + @InternalApi + public String getResolvedApiaryEndpoint(String serviceName) { + String resolvedUniverseDomain = + getUniverseDomain() != null ? getUniverseDomain() : GOOGLE_DEFAULT_UNIVERSE; + return formatTemplate(serviceName, resolvedUniverseDomain); + } + + private String formatTemplate(String serviceName, String universeDomain) { + return ENDPOINT_TEMPLATE + .replace("SERVICE_NAME", serviceName) + .replace("UNIVERSE_DOMAIN", universeDomain); + } } From 9ba6313d55a7d1fb9d931645bfdaf51823700e52 Mon Sep 17 00:00:00 2001 From: Lawrence Qiu Date: Mon, 18 Dec 2023 11:22:14 -0500 Subject: [PATCH 02/21] chore: Move validate universe domain logic to ServiceOptions --- .../src/main/java/com/google/cloud/BaseService.java | 12 ------------ .../main/java/com/google/cloud/ServiceOptions.java | 10 ++++++++++ 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/java-core/google-cloud-core/src/main/java/com/google/cloud/BaseService.java b/java-core/google-cloud-core/src/main/java/com/google/cloud/BaseService.java index c3901c1eab..f0e17c8764 100644 --- a/java-core/google-cloud-core/src/main/java/com/google/cloud/BaseService.java +++ b/java-core/google-cloud-core/src/main/java/com/google/cloud/BaseService.java @@ -17,10 +17,8 @@ package com.google.cloud; import com.google.api.core.InternalApi; -import com.google.auth.Credentials; import com.google.auth.Retryable; import com.google.cloud.ExceptionHandler.Interceptor; -import java.io.IOException; /** * Base class for service objects. @@ -70,14 +68,4 @@ protected BaseService(OptionsT options) { public OptionsT getOptions() { return options; } - - public boolean isValidUniverseDomain() throws IOException { - Credentials credentials = getOptions().getCredentials(); - String universeDomain = getOptions().getUniverseDomain(); - if (universeDomain == null) { - universeDomain = ServiceOptions.GOOGLE_DEFAULT_UNIVERSE; - } - return true; - // return credentials.getUniverseDomain() != universeDomain; - } } diff --git a/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java b/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java index 784159c558..3e20b2014e 100644 --- a/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java +++ b/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java @@ -815,4 +815,14 @@ private String formatTemplate(String serviceName, String universeDomain) { .replace("SERVICE_NAME", serviceName) .replace("UNIVERSE_DOMAIN", universeDomain); } + + public boolean isValidUniverseDomain() throws IOException { + Credentials credentials = getCredentials(); + String universeDomain = getUniverseDomain(); + if (universeDomain == null) { + universeDomain = ServiceOptions.GOOGLE_DEFAULT_UNIVERSE; + } + return true; + // return credentials.getUniverseDomain() != universeDomain; + } } From b0e761490e49d81229d8f68a783272ea558d33ec Mon Sep 17 00:00:00 2001 From: Lawrence Qiu Date: Tue, 2 Jan 2024 12:24:59 -0500 Subject: [PATCH 03/21] chore: Add javadocs --- .../java/com/google/cloud/BaseService.java | 27 +++++++++++----- .../java/com/google/cloud/ServiceOptions.java | 31 ++++++++----------- 2 files changed, 32 insertions(+), 26 deletions(-) diff --git a/java-core/google-cloud-core/src/main/java/com/google/cloud/BaseService.java b/java-core/google-cloud-core/src/main/java/com/google/cloud/BaseService.java index f0e17c8764..59527a0e67 100644 --- a/java-core/google-cloud-core/src/main/java/com/google/cloud/BaseService.java +++ b/java-core/google-cloud-core/src/main/java/com/google/cloud/BaseService.java @@ -16,9 +16,12 @@ package com.google.cloud; +import static com.google.cloud.ServiceOptions.GOOGLE_DEFAULT_UNIVERSE; + import com.google.api.core.InternalApi; -import com.google.auth.Retryable; +import com.google.auth.Credentials; import com.google.cloud.ExceptionHandler.Interceptor; +import java.io.IOException; /** * Base class for service objects. @@ -40,15 +43,13 @@ public RetryResult afterEval(Exception exception, RetryResult retryResult) { @Override public RetryResult beforeEval(Exception exception) { - boolean retryable = false; if (exception instanceof BaseServiceException) { - retryable = ((BaseServiceException) exception).isRetryable(); - } else if (exception instanceof Retryable) { - retryable = ((Retryable) exception).isRetryable(); + boolean retriable = ((BaseServiceException) exception).isRetryable(); + return retriable + ? Interceptor.RetryResult.RETRY + : Interceptor.RetryResult.CONTINUE_EVALUATION; } - return retryable - ? Interceptor.RetryResult.RETRY - : Interceptor.RetryResult.CONTINUE_EVALUATION; + return Interceptor.RetryResult.CONTINUE_EVALUATION; } }; public static final ExceptionHandler EXCEPTION_HANDLER = @@ -68,4 +69,14 @@ protected BaseService(OptionsT options) { public OptionsT getOptions() { return options; } + + /** Validates that Credentials' Universe Domain and user configured Universe Domain matches. */ + public boolean isValidUniverseDomain() throws IOException { + Credentials credentials = options.getCredentials(); + String universeDomain = options.getUniverseDomain(); + String resolvedUniverseDomain = + universeDomain != null ? universeDomain : GOOGLE_DEFAULT_UNIVERSE; + return true; + // return credentials.getUniverseDomain() != resolvedUniverseDomain; + } } diff --git a/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java b/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java index 3e20b2014e..0d97e266a0 100644 --- a/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java +++ b/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java @@ -87,7 +87,6 @@ public abstract class ServiceOptions< private static final String DEFAULT_HOST = "https://www.googleapis.com"; private static final String LEGACY_PROJECT_ENV_NAME = "GCLOUD_PROJECT"; private static final String PROJECT_ENV_NAME = "GOOGLE_CLOUD_PROJECT"; - private static final String ENDPOINT_TEMPLATE = "SERVICE_NAME.UNIVERSE_DOMAIN:443"; private static final RetrySettings DEFAULT_RETRY_SETTINGS = getDefaultRetrySettingsBuilder().build(); @@ -206,9 +205,10 @@ public B setHost(String host) { } /** - * Sets the Universe Domain. - * - * @return the builder + * Universe Domain is the domain for Google Cloud Services. It follows the format of + * `{ServiceName}.{UniverseDomain}`. For example, speech.googleapis.com would have a Universe + * Domain value of `googleapis.com` and cloudasset.test.com would have a Universe Domain of + * `test.com`. If this value is not set, this will default to `googleapis.com`. */ public B setUniverseDomain(String universeDomain) { this.universeDomain = universeDomain; @@ -599,7 +599,12 @@ public String getProjectId() { return projectId; } - /** Returns the Universe Domain */ + /** + * Universe Domain is the domain for Google Cloud Services. It follows the format of + * `{ServiceName}.{UniverseDomain}`. For example, speech.googleapis.com would have a Universe + * Domain value of `googleapis.com` and cloudasset.test.com would have a Universe Domain of + * `test.com`. If this value is not set, this will default to `googleapis.com`. + */ public String getUniverseDomain() { return universeDomain; } @@ -790,6 +795,7 @@ public String getQuotaProjectId() { return quotaProjectId; } + /** Returns the resolved endpoint for the Service to connect to Google Cloud */ public String getResolvedEndpoint(String serviceName) { if (universeDomain == null) { return formatTemplate(serviceName, GOOGLE_DEFAULT_UNIVERSE); @@ -803,6 +809,7 @@ public String getResolvedEndpoint(String serviceName) { } } + // Temporarily used for Apiary Wrapped Libraries. To be removed in the future. @InternalApi public String getResolvedApiaryEndpoint(String serviceName) { String resolvedUniverseDomain = @@ -811,18 +818,6 @@ public String getResolvedApiaryEndpoint(String serviceName) { } private String formatTemplate(String serviceName, String universeDomain) { - return ENDPOINT_TEMPLATE - .replace("SERVICE_NAME", serviceName) - .replace("UNIVERSE_DOMAIN", universeDomain); - } - - public boolean isValidUniverseDomain() throws IOException { - Credentials credentials = getCredentials(); - String universeDomain = getUniverseDomain(); - if (universeDomain == null) { - universeDomain = ServiceOptions.GOOGLE_DEFAULT_UNIVERSE; - } - return true; - // return credentials.getUniverseDomain() != universeDomain; + return serviceName + "." + universeDomain + ":443"; } } From 6cc86ac9fed632ae21b52922d84ad6e30fbe8f5c Mon Sep 17 00:00:00 2001 From: Lawrence Qiu Date: Tue, 2 Jan 2024 13:28:14 -0500 Subject: [PATCH 04/21] chore: Add tests --- .../java/com/google/cloud/BaseService.java | 10 ----- .../java/com/google/cloud/ServiceOptions.java | 12 ++++- .../com/google/cloud/ServiceOptionsTest.java | 45 +++++++++++++++++++ 3 files changed, 56 insertions(+), 11 deletions(-) diff --git a/java-core/google-cloud-core/src/main/java/com/google/cloud/BaseService.java b/java-core/google-cloud-core/src/main/java/com/google/cloud/BaseService.java index 59527a0e67..89e07577c9 100644 --- a/java-core/google-cloud-core/src/main/java/com/google/cloud/BaseService.java +++ b/java-core/google-cloud-core/src/main/java/com/google/cloud/BaseService.java @@ -69,14 +69,4 @@ protected BaseService(OptionsT options) { public OptionsT getOptions() { return options; } - - /** Validates that Credentials' Universe Domain and user configured Universe Domain matches. */ - public boolean isValidUniverseDomain() throws IOException { - Credentials credentials = options.getCredentials(); - String universeDomain = options.getUniverseDomain(); - String resolvedUniverseDomain = - universeDomain != null ? universeDomain : GOOGLE_DEFAULT_UNIVERSE; - return true; - // return credentials.getUniverseDomain() != resolvedUniverseDomain; - } } diff --git a/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java b/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java index 0d97e266a0..8d2455f645 100644 --- a/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java +++ b/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java @@ -800,7 +800,7 @@ public String getResolvedEndpoint(String serviceName) { if (universeDomain == null) { return formatTemplate(serviceName, GOOGLE_DEFAULT_UNIVERSE); } else if (Strings.isNullOrEmpty(universeDomain)) { - throw new RuntimeException("Universe Domain cannot be empty"); + throw new IllegalArgumentException("Universe Domain cannot be empty"); } else { if (host == null) { return formatTemplate(serviceName, getUniverseDomain()); @@ -817,6 +817,16 @@ public String getResolvedApiaryEndpoint(String serviceName) { return formatTemplate(serviceName, resolvedUniverseDomain); } + /** Validates that Credentials' Universe Domain and user configured Universe Domain matches. */ + public boolean isValidUniverseDomain() throws IOException { + Credentials credentials = getCredentials(); + String universeDomain = getUniverseDomain(); + String resolvedUniverseDomain = + universeDomain != null ? universeDomain : GOOGLE_DEFAULT_UNIVERSE; + return true; + // return credentials.getUniverseDomain() != resolvedUniverseDomain; + } + private String formatTemplate(String serviceName, String universeDomain) { return serviceName + "." + universeDomain + ":443"; } diff --git a/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java b/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java index bf75fca161..03cbe3ed18 100644 --- a/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java +++ b/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java @@ -22,6 +22,7 @@ import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -471,6 +472,50 @@ public void testResponseHeaderDoesNotContainMetaDataFlavor() throws Exception { assertThat(ServiceOptions.headerContainsMetadataFlavor(httpResponse)).isFalse(); } + @Test + public void testGetResolvedEndpoint_noUniverseDomain() { + TestServiceOptions options = TestServiceOptions.newBuilder().build(); + assertThat(options.getResolvedEndpoint("service")).isEqualTo("service.googleapis.com:443"); + } + + @Test + public void testGetResolvedEndpoint_emptyUniverseDomain() { + TestServiceOptions options = TestServiceOptions.newBuilder().setUniverseDomain("").build(); + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> options.getResolvedEndpoint("service")); + assertThat(exception.getMessage()).isEqualTo("Universe Domain cannot be empty"); + } + + @Test + public void testGetResolvedEndpoint_customUniverseDomain_noHost() { + TestServiceOptions options = TestServiceOptions.newBuilder().setUniverseDomain("test.com").setHost(null).build(); + // `https://www.googleapis.com` is the DEFAULT_HOST value. It is set as the host if host is null + assertThat(options.getResolvedEndpoint("service")).isEqualTo("https://www.googleapis.com"); + } + + @Test + public void testGetResolvedEndpoint_customUniverseDomain_customHost() { + TestServiceOptions options = TestServiceOptions.newBuilder().setUniverseDomain("test.com").setHost("service.random.com:443").build(); + assertThat(options.getResolvedEndpoint("service")).isEqualTo("service.random.com:443"); + } + + @Test + public void testGetResolvedApiaryEndpoint_noUniverseDomain() { + TestServiceOptions options = TestServiceOptions.newBuilder().build(); + assertThat(options.getResolvedApiaryEndpoint("service")).isEqualTo("service.googleapis.com:443"); + } + + @Test + public void testGetResolvedApiaryEndpoint_customUniverseDomain_noHost() { + TestServiceOptions options = TestServiceOptions.newBuilder().setUniverseDomain("test.com").setHost(null).build(); + assertThat(options.getResolvedApiaryEndpoint("service")).isEqualTo("service.test.com:443"); + } + + @Test + public void testGetResolvedApiaryEndpoint_customUniverseDomain_customHost() { + TestServiceOptions options = TestServiceOptions.newBuilder().setUniverseDomain("test.com").setHost("service.random.com:443").build(); + assertThat(options.getResolvedEndpoint("service")).isEqualTo("service.random.com:443"); + } + private HttpResponse createHttpResponseWithHeader(final Multimap headers) throws Exception { HttpTransport mockHttpTransport = From c68e996e5e3b0f0b90c88e3400084ff8ca251846 Mon Sep 17 00:00:00 2001 From: Lawrence Qiu Date: Tue, 2 Jan 2024 13:30:47 -0500 Subject: [PATCH 05/21] chore: Fix lint issues --- .../java/com/google/cloud/BaseService.java | 3 --- .../java/com/google/cloud/ServiceOptions.java | 2 +- .../com/google/cloud/ServiceOptionsTest.java | 24 ++++++++++++++----- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/java-core/google-cloud-core/src/main/java/com/google/cloud/BaseService.java b/java-core/google-cloud-core/src/main/java/com/google/cloud/BaseService.java index 89e07577c9..1167fec6eb 100644 --- a/java-core/google-cloud-core/src/main/java/com/google/cloud/BaseService.java +++ b/java-core/google-cloud-core/src/main/java/com/google/cloud/BaseService.java @@ -16,12 +16,9 @@ package com.google.cloud; -import static com.google.cloud.ServiceOptions.GOOGLE_DEFAULT_UNIVERSE; import com.google.api.core.InternalApi; -import com.google.auth.Credentials; import com.google.cloud.ExceptionHandler.Interceptor; -import java.io.IOException; /** * Base class for service objects. diff --git a/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java b/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java index 8d2455f645..671b679e8d 100644 --- a/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java +++ b/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java @@ -822,7 +822,7 @@ public boolean isValidUniverseDomain() throws IOException { Credentials credentials = getCredentials(); String universeDomain = getUniverseDomain(); String resolvedUniverseDomain = - universeDomain != null ? universeDomain : GOOGLE_DEFAULT_UNIVERSE; + universeDomain != null ? universeDomain : GOOGLE_DEFAULT_UNIVERSE; return true; // return credentials.getUniverseDomain() != resolvedUniverseDomain; } diff --git a/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java b/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java index 03cbe3ed18..718181b5c4 100644 --- a/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java +++ b/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java @@ -481,38 +481,50 @@ public void testGetResolvedEndpoint_noUniverseDomain() { @Test public void testGetResolvedEndpoint_emptyUniverseDomain() { TestServiceOptions options = TestServiceOptions.newBuilder().setUniverseDomain("").build(); - IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> options.getResolvedEndpoint("service")); + IllegalArgumentException exception = + assertThrows(IllegalArgumentException.class, () -> options.getResolvedEndpoint("service")); assertThat(exception.getMessage()).isEqualTo("Universe Domain cannot be empty"); } @Test public void testGetResolvedEndpoint_customUniverseDomain_noHost() { - TestServiceOptions options = TestServiceOptions.newBuilder().setUniverseDomain("test.com").setHost(null).build(); + TestServiceOptions options = + TestServiceOptions.newBuilder().setUniverseDomain("test.com").setHost(null).build(); // `https://www.googleapis.com` is the DEFAULT_HOST value. It is set as the host if host is null assertThat(options.getResolvedEndpoint("service")).isEqualTo("https://www.googleapis.com"); } @Test public void testGetResolvedEndpoint_customUniverseDomain_customHost() { - TestServiceOptions options = TestServiceOptions.newBuilder().setUniverseDomain("test.com").setHost("service.random.com:443").build(); + TestServiceOptions options = + TestServiceOptions.newBuilder() + .setUniverseDomain("test.com") + .setHost("service.random.com:443") + .build(); assertThat(options.getResolvedEndpoint("service")).isEqualTo("service.random.com:443"); } @Test public void testGetResolvedApiaryEndpoint_noUniverseDomain() { TestServiceOptions options = TestServiceOptions.newBuilder().build(); - assertThat(options.getResolvedApiaryEndpoint("service")).isEqualTo("service.googleapis.com:443"); + assertThat(options.getResolvedApiaryEndpoint("service")) + .isEqualTo("service.googleapis.com:443"); } @Test public void testGetResolvedApiaryEndpoint_customUniverseDomain_noHost() { - TestServiceOptions options = TestServiceOptions.newBuilder().setUniverseDomain("test.com").setHost(null).build(); + TestServiceOptions options = + TestServiceOptions.newBuilder().setUniverseDomain("test.com").setHost(null).build(); assertThat(options.getResolvedApiaryEndpoint("service")).isEqualTo("service.test.com:443"); } @Test public void testGetResolvedApiaryEndpoint_customUniverseDomain_customHost() { - TestServiceOptions options = TestServiceOptions.newBuilder().setUniverseDomain("test.com").setHost("service.random.com:443").build(); + TestServiceOptions options = + TestServiceOptions.newBuilder() + .setUniverseDomain("test.com") + .setHost("service.random.com:443") + .build(); assertThat(options.getResolvedEndpoint("service")).isEqualTo("service.random.com:443"); } From 2c2373242bd30d39c634dd9e70f4e0f6ac3b5c88 Mon Sep 17 00:00:00 2001 From: Lawrence Qiu Date: Tue, 2 Jan 2024 14:00:24 -0500 Subject: [PATCH 06/21] chore: Add project id to tests --- .../java/com/google/cloud/BaseService.java | 1 - .../com/google/cloud/ServiceOptionsTest.java | 21 ++++++++++++++----- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/java-core/google-cloud-core/src/main/java/com/google/cloud/BaseService.java b/java-core/google-cloud-core/src/main/java/com/google/cloud/BaseService.java index 1167fec6eb..781f29b421 100644 --- a/java-core/google-cloud-core/src/main/java/com/google/cloud/BaseService.java +++ b/java-core/google-cloud-core/src/main/java/com/google/cloud/BaseService.java @@ -16,7 +16,6 @@ package com.google.cloud; - import com.google.api.core.InternalApi; import com.google.cloud.ExceptionHandler.Interceptor; diff --git a/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java b/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java index 718181b5c4..82736c4a68 100644 --- a/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java +++ b/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java @@ -474,13 +474,14 @@ public void testResponseHeaderDoesNotContainMetaDataFlavor() throws Exception { @Test public void testGetResolvedEndpoint_noUniverseDomain() { - TestServiceOptions options = TestServiceOptions.newBuilder().build(); + TestServiceOptions options = TestServiceOptions.newBuilder().setProjectId("project-id").build(); assertThat(options.getResolvedEndpoint("service")).isEqualTo("service.googleapis.com:443"); } @Test public void testGetResolvedEndpoint_emptyUniverseDomain() { - TestServiceOptions options = TestServiceOptions.newBuilder().setUniverseDomain("").build(); + TestServiceOptions options = + TestServiceOptions.newBuilder().setUniverseDomain("").setProjectId("project-id").build(); IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> options.getResolvedEndpoint("service")); assertThat(exception.getMessage()).isEqualTo("Universe Domain cannot be empty"); @@ -489,7 +490,11 @@ public void testGetResolvedEndpoint_emptyUniverseDomain() { @Test public void testGetResolvedEndpoint_customUniverseDomain_noHost() { TestServiceOptions options = - TestServiceOptions.newBuilder().setUniverseDomain("test.com").setHost(null).build(); + TestServiceOptions.newBuilder() + .setUniverseDomain("test.com") + .setHost(null) + .setProjectId("project-id") + .build(); // `https://www.googleapis.com` is the DEFAULT_HOST value. It is set as the host if host is null assertThat(options.getResolvedEndpoint("service")).isEqualTo("https://www.googleapis.com"); } @@ -500,13 +505,14 @@ public void testGetResolvedEndpoint_customUniverseDomain_customHost() { TestServiceOptions.newBuilder() .setUniverseDomain("test.com") .setHost("service.random.com:443") + .setProjectId("project-id") .build(); assertThat(options.getResolvedEndpoint("service")).isEqualTo("service.random.com:443"); } @Test public void testGetResolvedApiaryEndpoint_noUniverseDomain() { - TestServiceOptions options = TestServiceOptions.newBuilder().build(); + TestServiceOptions options = TestServiceOptions.newBuilder().setProjectId("project-id").build(); assertThat(options.getResolvedApiaryEndpoint("service")) .isEqualTo("service.googleapis.com:443"); } @@ -514,7 +520,11 @@ public void testGetResolvedApiaryEndpoint_noUniverseDomain() { @Test public void testGetResolvedApiaryEndpoint_customUniverseDomain_noHost() { TestServiceOptions options = - TestServiceOptions.newBuilder().setUniverseDomain("test.com").setHost(null).build(); + TestServiceOptions.newBuilder() + .setUniverseDomain("test.com") + .setHost(null) + .setProjectId("project-id") + .build(); assertThat(options.getResolvedApiaryEndpoint("service")).isEqualTo("service.test.com:443"); } @@ -524,6 +534,7 @@ public void testGetResolvedApiaryEndpoint_customUniverseDomain_customHost() { TestServiceOptions.newBuilder() .setUniverseDomain("test.com") .setHost("service.random.com:443") + .setProjectId("project-id") .build(); assertThat(options.getResolvedEndpoint("service")).isEqualTo("service.random.com:443"); } From db4965a247d2db9ac2b7c1f063f0dfae06181c21 Mon Sep 17 00:00:00 2001 From: Lawrence Qiu Date: Tue, 2 Jan 2024 14:23:10 -0500 Subject: [PATCH 07/21] chore: Fix format issues --- .../src/main/java/com/google/cloud/ServiceOptions.java | 8 ++++---- .../test/java/com/google/cloud/ServiceOptionsTest.java | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java b/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java index 671b679e8d..978f39be69 100644 --- a/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java +++ b/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java @@ -798,12 +798,12 @@ public String getQuotaProjectId() { /** Returns the resolved endpoint for the Service to connect to Google Cloud */ public String getResolvedEndpoint(String serviceName) { if (universeDomain == null) { - return formatTemplate(serviceName, GOOGLE_DEFAULT_UNIVERSE); + return formatEndpoint(serviceName, GOOGLE_DEFAULT_UNIVERSE); } else if (Strings.isNullOrEmpty(universeDomain)) { throw new IllegalArgumentException("Universe Domain cannot be empty"); } else { if (host == null) { - return formatTemplate(serviceName, getUniverseDomain()); + return formatEndpoint(serviceName, getUniverseDomain()); } return host; } @@ -814,7 +814,7 @@ public String getResolvedEndpoint(String serviceName) { public String getResolvedApiaryEndpoint(String serviceName) { String resolvedUniverseDomain = getUniverseDomain() != null ? getUniverseDomain() : GOOGLE_DEFAULT_UNIVERSE; - return formatTemplate(serviceName, resolvedUniverseDomain); + return formatEndpoint(serviceName, resolvedUniverseDomain); } /** Validates that Credentials' Universe Domain and user configured Universe Domain matches. */ @@ -827,7 +827,7 @@ public boolean isValidUniverseDomain() throws IOException { // return credentials.getUniverseDomain() != resolvedUniverseDomain; } - private String formatTemplate(String serviceName, String universeDomain) { + private String formatEndpoint(String serviceName, String universeDomain) { return serviceName + "." + universeDomain + ":443"; } } diff --git a/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java b/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java index 82736c4a68..729ef000ea 100644 --- a/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java +++ b/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java @@ -495,7 +495,8 @@ public void testGetResolvedEndpoint_customUniverseDomain_noHost() { .setHost(null) .setProjectId("project-id") .build(); - // `https://www.googleapis.com` is the DEFAULT_HOST value. It is set as the host if host is null + // `https://www.googleapis.com` is the DEFAULT_HOST value for ServiceOptions. The ServiceOptions + // builder will set as it as the host if host is null assertThat(options.getResolvedEndpoint("service")).isEqualTo("https://www.googleapis.com"); } From 3d63297d7976ce6b8ee939d2dd997471f99d2eb1 Mon Sep 17 00:00:00 2001 From: Lawrence Qiu Date: Wed, 3 Jan 2024 13:00:05 -0500 Subject: [PATCH 08/21] chore: Address PR comments --- .../java/com/google/cloud/ServiceOptions.java | 33 +++++++++++++++---- .../com/google/cloud/ServiceOptionsTest.java | 6 ++-- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java b/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java index 978f39be69..8ab89b54fd 100644 --- a/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java +++ b/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java @@ -46,7 +46,6 @@ import com.google.auth.oauth2.ServiceAccountCredentials; import com.google.cloud.spi.ServiceRpcFactory; import com.google.common.base.Preconditions; -import com.google.common.base.Strings; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; @@ -60,6 +59,7 @@ import java.io.InputStream; import java.io.ObjectInputStream; import java.io.Serializable; +import java.net.URI; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.Locale; @@ -795,18 +795,39 @@ public String getQuotaProjectId() { return quotaProjectId; } - /** Returns the resolved endpoint for the Service to connect to Google Cloud */ + /** + * Returns the resolved endpoint for the Service to connect to Google Cloud + * + *

The resolved endpoint is always in `host:port` format + */ public String getResolvedEndpoint(String serviceName) { if (universeDomain == null) { return formatEndpoint(serviceName, GOOGLE_DEFAULT_UNIVERSE); - } else if (Strings.isNullOrEmpty(universeDomain)) { + } else if (universeDomain.isEmpty()) { throw new IllegalArgumentException("Universe Domain cannot be empty"); } else { - if (host == null) { - return formatEndpoint(serviceName, getUniverseDomain()); + if (host != null) { + return normalizeEndpoint(host); } - return host; + return formatEndpoint(serviceName, getUniverseDomain()); + } + } + + /** Host parameter is expected in the format of {scheme}:{host} */ + private String normalizeEndpoint(String host) { + URI uri = URI.create(host); + String scheme = uri.getScheme(); + int port = uri.getPort(); + + // http:// defaults to 80, https:// or no scheme default to 443 + if ("http".equals(scheme)) { + port = port > 0 ? port : 80; + } else if ("https".equals(scheme)) { + port = port > 0 ? port : 443; + } else { + port = 443; } + return String.format("%s:%s", uri.getHost(), port); } // Temporarily used for Apiary Wrapped Libraries. To be removed in the future. diff --git a/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java b/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java index 729ef000ea..bacc8448ac 100644 --- a/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java +++ b/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java @@ -497,7 +497,7 @@ public void testGetResolvedEndpoint_customUniverseDomain_noHost() { .build(); // `https://www.googleapis.com` is the DEFAULT_HOST value for ServiceOptions. The ServiceOptions // builder will set as it as the host if host is null - assertThat(options.getResolvedEndpoint("service")).isEqualTo("https://www.googleapis.com"); + assertThat(options.getResolvedEndpoint("service")).isEqualTo("www.googleapis.com:443"); } @Test @@ -505,7 +505,7 @@ public void testGetResolvedEndpoint_customUniverseDomain_customHost() { TestServiceOptions options = TestServiceOptions.newBuilder() .setUniverseDomain("test.com") - .setHost("service.random.com:443") + .setHost("https://service.random.com") .setProjectId("project-id") .build(); assertThat(options.getResolvedEndpoint("service")).isEqualTo("service.random.com:443"); @@ -534,7 +534,7 @@ public void testGetResolvedApiaryEndpoint_customUniverseDomain_customHost() { TestServiceOptions options = TestServiceOptions.newBuilder() .setUniverseDomain("test.com") - .setHost("service.random.com:443") + .setHost("https://service.random.com") .setProjectId("project-id") .build(); assertThat(options.getResolvedEndpoint("service")).isEqualTo("service.random.com:443"); From 5f8d48fd0910f70aa68fc10eafb93c87321e5918 Mon Sep 17 00:00:00 2001 From: Lawrence Qiu Date: Wed, 3 Jan 2024 16:35:07 -0500 Subject: [PATCH 09/21] chore: Update Apiary to return rootHostUrl --- .../java/com/google/cloud/ServiceOptions.java | 39 +++++++++++-------- .../com/google/cloud/ServiceOptionsTest.java | 14 +++---- 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java b/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java index 8ab89b54fd..bbda836d52 100644 --- a/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java +++ b/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java @@ -813,29 +813,40 @@ public String getResolvedEndpoint(String serviceName) { } } - /** Host parameter is expected in the format of {scheme}:{host} */ + private String formatEndpoint(String serviceName, String universeDomain) { + return serviceName + "." + universeDomain + ":443"; + } + private String normalizeEndpoint(String host) { URI uri = URI.create(host); String scheme = uri.getScheme(); int port = uri.getPort(); - // http:// defaults to 80, https:// or no scheme default to 443 - if ("http".equals(scheme)) { - port = port > 0 ? port : 80; - } else if ("https".equals(scheme)) { - port = port > 0 ? port : 443; - } else { - port = 443; + // If no port is provided, http:// defaults to 80 and https:// defaults to 443 + if (scheme.equals("http")) { + return String.format("%s:%s", uri.getHost(), port > 0 ? port : 80); + } else if (scheme.equals("https")) { + return String.format("%s:%s", uri.getHost(), port > 0 ? port : 443); + } + // If scheme does not match above, then host does not have a valid scheme. The + // host param value is probably in format {host}:{port}. + if (host.contains(":")) { + return host; } - return String.format("%s:%s", uri.getHost(), port); + // If the scheme and port are not provided, default to 443 + return host + ":443"; } - // Temporarily used for Apiary Wrapped Libraries. To be removed in the future. + /** + * Temporarily used for BigQuery and Storage Apiary Wrapped Libraries. To be removed in the + * future. Returns the host to be used for the rootUrl and output is in format of: + * "https://serviceName.universeDomain/" + */ @InternalApi - public String getResolvedApiaryEndpoint(String serviceName) { + public String getResolvedApiaryHost(String serviceName) { String resolvedUniverseDomain = getUniverseDomain() != null ? getUniverseDomain() : GOOGLE_DEFAULT_UNIVERSE; - return formatEndpoint(serviceName, resolvedUniverseDomain); + return "https://" + serviceName + "." + resolvedUniverseDomain + "/"; } /** Validates that Credentials' Universe Domain and user configured Universe Domain matches. */ @@ -847,8 +858,4 @@ public boolean isValidUniverseDomain() throws IOException { return true; // return credentials.getUniverseDomain() != resolvedUniverseDomain; } - - private String formatEndpoint(String serviceName, String universeDomain) { - return serviceName + "." + universeDomain + ":443"; - } } diff --git a/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java b/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java index bacc8448ac..17a4fe4c59 100644 --- a/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java +++ b/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java @@ -512,32 +512,32 @@ public void testGetResolvedEndpoint_customUniverseDomain_customHost() { } @Test - public void testGetResolvedApiaryEndpoint_noUniverseDomain() { + public void testGetResolvedApiaryHost_noUniverseDomain() { TestServiceOptions options = TestServiceOptions.newBuilder().setProjectId("project-id").build(); - assertThat(options.getResolvedApiaryEndpoint("service")) - .isEqualTo("service.googleapis.com:443"); + assertThat(options.getResolvedApiaryHost("service")) + .isEqualTo("https://service.googleapis.com/"); } @Test - public void testGetResolvedApiaryEndpoint_customUniverseDomain_noHost() { + public void testGetResolvedApiaryHost_customUniverseDomain_noHost() { TestServiceOptions options = TestServiceOptions.newBuilder() .setUniverseDomain("test.com") .setHost(null) .setProjectId("project-id") .build(); - assertThat(options.getResolvedApiaryEndpoint("service")).isEqualTo("service.test.com:443"); + assertThat(options.getResolvedApiaryHost("service")).isEqualTo("https://service.test.com/"); } @Test - public void testGetResolvedApiaryEndpoint_customUniverseDomain_customHost() { + public void testGetResolvedApiaryHost_customUniverseDomain_customHost() { TestServiceOptions options = TestServiceOptions.newBuilder() .setUniverseDomain("test.com") .setHost("https://service.random.com") .setProjectId("project-id") .build(); - assertThat(options.getResolvedEndpoint("service")).isEqualTo("service.random.com:443"); + assertThat(options.getResolvedApiaryHost("service")).isEqualTo("https://service.test.com/"); } private HttpResponse createHttpResponseWithHeader(final Multimap headers) From 8fcf8323a3c3870a8d8bc2d36282ff62bb79d9a6 Mon Sep 17 00:00:00 2001 From: Lawrence Qiu Date: Wed, 3 Jan 2024 17:30:51 -0500 Subject: [PATCH 10/21] chore: Use Google Auth Library v1.21.0 --- gapic-generator-java-pom-parent/pom.xml | 2 +- .../java/com/google/cloud/ServiceOptions.java | 18 ++-- .../com/google/cloud/ServiceOptionsTest.java | 98 ++++++++++++++++++- 3 files changed, 103 insertions(+), 15 deletions(-) diff --git a/gapic-generator-java-pom-parent/pom.xml b/gapic-generator-java-pom-parent/pom.xml index 4755b57410..3655466b4d 100644 --- a/gapic-generator-java-pom-parent/pom.xml +++ b/gapic-generator-java-pom-parent/pom.xml @@ -27,7 +27,7 @@ consistent across modules in this repository --> 1.3.2 1.59.1 - 1.20.0 + 1.21.0 1.43.3 2.10.1 32.1.3-jre diff --git a/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java b/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java index bbda836d52..5a799a9c42 100644 --- a/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java +++ b/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java @@ -82,8 +82,6 @@ public abstract class ServiceOptions< implements Serializable { public static final String CREDENTIAL_ENV_NAME = "GOOGLE_APPLICATION_CREDENTIALS"; - public static final String GOOGLE_DEFAULT_UNIVERSE = "googleapis.com"; - private static final String DEFAULT_HOST = "https://www.googleapis.com"; private static final String LEGACY_PROJECT_ENV_NAME = "GCLOUD_PROJECT"; private static final String PROJECT_ENV_NAME = "GOOGLE_CLOUD_PROJECT"; @@ -802,7 +800,7 @@ public String getQuotaProjectId() { */ public String getResolvedEndpoint(String serviceName) { if (universeDomain == null) { - return formatEndpoint(serviceName, GOOGLE_DEFAULT_UNIVERSE); + return formatEndpoint(serviceName, Credentials.GOOGLE_DEFAULT_UNIVERSE); } else if (universeDomain.isEmpty()) { throw new IllegalArgumentException("Universe Domain cannot be empty"); } else { @@ -817,6 +815,7 @@ private String formatEndpoint(String serviceName, String universeDomain) { return serviceName + "." + universeDomain + ":443"; } + // Best effort endpoint normalization to ensure it results in {host}:{port} format private String normalizeEndpoint(String host) { URI uri = URI.create(host); String scheme = uri.getScheme(); @@ -839,23 +838,20 @@ private String normalizeEndpoint(String host) { /** * Temporarily used for BigQuery and Storage Apiary Wrapped Libraries. To be removed in the - * future. Returns the host to be used for the rootUrl and output is in format of: + * future. Returns the host to be used for the rootUrl and output is in the format of: * "https://serviceName.universeDomain/" */ @InternalApi public String getResolvedApiaryHost(String serviceName) { String resolvedUniverseDomain = - getUniverseDomain() != null ? getUniverseDomain() : GOOGLE_DEFAULT_UNIVERSE; + getUniverseDomain() != null ? getUniverseDomain() : Credentials.GOOGLE_DEFAULT_UNIVERSE; return "https://" + serviceName + "." + resolvedUniverseDomain + "/"; } - /** Validates that Credentials' Universe Domain and user configured Universe Domain matches. */ + /** Validates that Credentials' Universe Domain matches the user configured Universe Domain. */ public boolean isValidUniverseDomain() throws IOException { - Credentials credentials = getCredentials(); - String universeDomain = getUniverseDomain(); String resolvedUniverseDomain = - universeDomain != null ? universeDomain : GOOGLE_DEFAULT_UNIVERSE; - return true; - // return credentials.getUniverseDomain() != resolvedUniverseDomain; + getUniverseDomain() != null ? getUniverseDomain() : Credentials.GOOGLE_DEFAULT_UNIVERSE; + return resolvedUniverseDomain.equals(getCredentials().getUniverseDomain()); } } diff --git a/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java b/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java index 17a4fe4c59..16dfc28d54 100644 --- a/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java +++ b/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java @@ -56,6 +56,7 @@ public class ServiceOptionsTest { private static GoogleCredentials credentials; private static GoogleCredentials credentialsWithProjectId; private static GoogleCredentials credentialsWithQuotaProject; + private static GoogleCredentials credentialsNotInGDU; private static final String JSON_KEY = "{\n" @@ -82,7 +83,8 @@ public class ServiceOptionsTest { + "XyRDW4IG1Oa2p\\nrALStNBx5Y9t0/LQnFI4w3aG\\n-----END PRIVATE KEY-----\\n\",\n" + " \"client_email\": \"someclientid@developer.gserviceaccount.com\",\n" + " \"client_id\": \"someclientid.apps.googleusercontent.com\",\n" - + " \"type\": \"service_account\"\n" + + " \"type\": \"service_account\",\n" + + " \"universe_domain\": \"googleapis.com\"\n" + "}"; private static final String JSON_KEY_PROJECT_ID = @@ -111,7 +113,8 @@ public class ServiceOptionsTest { + " \"project_id\": \"someprojectid\",\n" + " \"client_email\": \"someclientid@developer.gserviceaccount.com\",\n" + " \"client_id\": \"someclientid.apps.googleusercontent.com\",\n" - + " \"type\": \"service_account\"\n" + + " \"type\": \"service_account\",\n" + + " \"universe_domain\": \"googleapis.com\"\n" + "}"; private static final String JSON_KEY_QUOTA_PROJECT_ID = @@ -141,13 +144,44 @@ public class ServiceOptionsTest { + " \"client_email\": \"someclientid@developer.gserviceaccount.com\",\n" + " \"client_id\": \"someclientid.apps.googleusercontent.com\",\n" + " \"type\": \"service_account\",\n" - + " \"quota_project_id\": \"some-quota-project-id\"\n" + + " \"quota_project_id\": \"some-quota-project-id\",\n" + + " \"universe_domain\": \"googleapis.com\"\n" + + "}"; + + private static final String JSON_KEY_NON_GDU = + "{\n" + + " \"private_key_id\": \"somekeyid\",\n" + + " \"private_key\": \"-----BEGIN PRIVATE KEY-----\\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggS" + + "kAgEAAoIBAQC+K2hSuFpAdrJI\\nnCgcDz2M7t7bjdlsadsasad+fvRSW6TjNQZ3p5LLQY1kSZRqBqylRkzteMOyHg" + + "aR\\n0Pmxh3ILCND5men43j3h4eDbrhQBuxfEMalkG92sL+PNQSETY2tnvXryOvmBRwa/\\nQP/9dJfIkIDJ9Fw9N4" + + "Bhhhp6mCcRpdQjV38H7JsyJ7lih/oNjECgYAt\\nknddadwkwewcVxHFhcZJO+XWf6ofLUXpRwiTZakGMn8EE1uVa2" + + "LgczOjwWHGi99MFjxSer5m9\\n1tCa3/KEGKiS/YL71JvjwX3mb+cewlkcmweBKZHM2JPTk0ZednFSpVZMtycjkbLa" + + "\\ndYOS8V85AgMBewECggEBAKksaldajfDZDV6nGqbFjMiizAKJolr/M3OQw16K6o3/\\n0S31xIe3sSlgW0+UbYlF" + + "4U8KifhManD1apVSC3csafaspP4RZUHFhtBywLO9pR5c\\nr6S5aLp+gPWFyIp1pfXbWGvc5VY/v9x7ya1VEa6rXvL" + + "sKupSeWAW4tMj3eo/64ge\\nsdaceaLYw52KeBYiT6+vpsnYrEkAHO1fF/LavbLLOFJmFTMxmsNaG0tuiJHgjshB\\" + + "n82DpMCbXG9YcCgI/DbzuIjsdj2JC1cascSP//3PmefWysucBQe7Jryb6NQtASmnv\\nCdDw/0jmZTEjpe4S1lxfHp" + + "lAhHFtdgYTvyYtaLZiVVkCgYEA8eVpof2rceecw/I6\\n5ng1q3Hl2usdWV/4mZMvR0fOemacLLfocX6IYxT1zA1FF" + + "JlbXSRsJMf/Qq39mOR2\\nSpW+hr4jCoHeRVYLgsbggtrevGmILAlNoqCMpGZ6vDmJpq6ECV9olliDvpPgWOP+\\nm" + + "YPDreFBGxWvQrADNbRt2dmGsrsCgYEAyUHqB2wvJHFqdmeBsaacewzV8x9WgmeX\\ngUIi9REwXlGDW0Mz50dxpxcK" + + "CAYn65+7TCnY5O/jmL0VRxU1J2mSWyWTo1C+17L0\\n3fUqjxL1pkefwecxwecvC+gFFYdJ4CQ/MHHXU81Lwl1iWdF" + + "Cd2UoGddYaOF+KNeM\\nHC7cmqra+JsCgYEAlUNywzq8nUg7282E+uICfCB0LfwejuymR93CtsFgb7cRd6ak\\nECR" + + "8FGfCpH8ruWJINllbQfcHVCX47ndLZwqv3oVFKh6pAS/vVI4dpOepP8++7y1u\\ncoOvtreXCX6XqfrWDtKIvv0vjl" + + "HBhhhp6mCcRpdQjV38H7JsyJ7lih/oNjECgYAt\\nkndj5uNl5SiuVxHFhcZJO+XWf6ofLUregtevZakGMn8EE1uVa" + + "2AY7eafmoU/nZPT\\n00YB0TBATdCbn/nBSuKDESkhSg9s2GEKQZG5hBmL5uCMfo09z3SfxZIhJdlerreP\\nJ7gSi" + + "dI12N+EZxYd4xIJh/HFDgp7RRO87f+WJkofMQKBgGTnClK1VMaCRbJZPriw\\nEfeFCoOX75MxKwXs6xgrw4W//AYG" + + "GUjDt83lD6AZP6tws7gJ2IwY/qP7+lyhjEqN\\nHtfPZRGFkGZsdaksdlaksd323423d+15/UvrlRSFPNj1tWQmNKk" + + "XyRDW4IG1Oa2p\\nrALStNBx5Y9t0/LQnFI4w3aG\\n-----END PRIVATE KEY-----\\n\",\n" + + " \"client_email\": \"someclientid@developer.gserviceaccount.com\",\n" + + " \"client_id\": \"someclientid.apps.googleusercontent.com\",\n" + + " \"type\": \"service_account\",\n" + + " \"universe_domain\": \"random.com\"\n" + "}"; static { credentials = loadCredentials(JSON_KEY); credentialsWithProjectId = loadCredentials(JSON_KEY_PROJECT_ID); credentialsWithQuotaProject = loadCredentials(JSON_KEY_QUOTA_PROJECT_ID); + credentialsNotInGDU = loadCredentials(JSON_KEY_NON_GDU); } static GoogleCredentials loadCredentials(String credentialFile) { @@ -540,6 +574,64 @@ public void testGetResolvedApiaryHost_customUniverseDomain_customHost() { assertThat(options.getResolvedApiaryHost("service")).isEqualTo("https://service.test.com/"); } + // No User Configuration = GDU, Default Credentials = GDU + @Test + public void testisValidUniverseDomain_noUserUniverseDomainConfig_defaultCredentials() + throws IOException { + TestServiceOptions options = + TestServiceOptions.newBuilder() + .setProjectId("project-id") + .setHost("https://test.random.com") + .setCredentials(credentials) + .build(); + assertThat(options.isValidUniverseDomain()).isTrue(); + } + + // No User Configuration = GDU, non Default Credentials = random.com + // non-GDU Credentials could be any domain, the tests use random.com + @Test + public void testisValidUniverseDomain_noUserUniverseDomainConfig_nonGDUCredentials() + throws IOException { + TestServiceOptions options = + TestServiceOptions.newBuilder() + .setProjectId("project-id") + .setHost("https://test.random.com") + .setCredentials(credentialsNotInGDU) + .build(); + assertThat(options.isValidUniverseDomain()).isFalse(); + } + + // User Configuration = random.com, Default Credentials = GDU + // User Credentials could be set to any domain, the tests use random.com + @Test + public void testisValidUniverseDomain_userUniverseDomainConfig_defaultCredentials() + throws IOException { + TestServiceOptions options = + TestServiceOptions.newBuilder() + .setProjectId("project-id") + .setHost("https://test.random.com") + .setUniverseDomain("random.com") + .setCredentials(credentials) + .build(); + assertThat(options.isValidUniverseDomain()).isFalse(); + } + + // User Configuration = random.com, non Default Credentials = random.com + // User Credentials and non GDU Credentials could be set to any domain, + // the tests use random.com + @Test + public void testisValidUniverseDomain_userUniverseDomainConfig_nonGDUCredentials() + throws IOException { + TestServiceOptions options = + TestServiceOptions.newBuilder() + .setProjectId("project-id") + .setHost("https://test.random.com") + .setUniverseDomain("random.com") + .setCredentials(credentialsNotInGDU) + .build(); + assertThat(options.isValidUniverseDomain()).isTrue(); + } + private HttpResponse createHttpResponseWithHeader(final Multimap headers) throws Exception { HttpTransport mockHttpTransport = From 8e878f97fa0a7e72ca25f6c69f256b6626d6b087 Mon Sep 17 00:00:00 2001 From: Lawrence Qiu Date: Wed, 3 Jan 2024 17:57:21 -0500 Subject: [PATCH 11/21] chore: Add tests for normalizeEndpoint() --- .../java/com/google/cloud/ServiceOptions.java | 18 ++--- .../com/google/cloud/ServiceOptionsTest.java | 65 +++++++++++++++++-- 2 files changed, 65 insertions(+), 18 deletions(-) diff --git a/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java b/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java index 5a799a9c42..9e638a32d9 100644 --- a/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java +++ b/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java @@ -805,7 +805,7 @@ public String getResolvedEndpoint(String serviceName) { throw new IllegalArgumentException("Universe Domain cannot be empty"); } else { if (host != null) { - return normalizeEndpoint(host); + return normalizeEndpoint(); } return formatEndpoint(serviceName, getUniverseDomain()); } @@ -815,8 +815,9 @@ private String formatEndpoint(String serviceName, String universeDomain) { return serviceName + "." + universeDomain + ":443"; } - // Best effort endpoint normalization to ensure it results in {host}:{port} format - private String normalizeEndpoint(String host) { + // Best effort endpoint normalization to ensure it results in {domain}:{port} format + // for gRPC-Java. `host` is expected to be in format of http(s)://{domain} + String normalizeEndpoint() { URI uri = URI.create(host); String scheme = uri.getScheme(); int port = uri.getPort(); @@ -826,14 +827,9 @@ private String normalizeEndpoint(String host) { return String.format("%s:%s", uri.getHost(), port > 0 ? port : 80); } else if (scheme.equals("https")) { return String.format("%s:%s", uri.getHost(), port > 0 ? port : 443); + } else { + throw new RuntimeException("Invalid host: " + host + ". Expecting http(s)://{domain}"); } - // If scheme does not match above, then host does not have a valid scheme. The - // host param value is probably in format {host}:{port}. - if (host.contains(":")) { - return host; - } - // If the scheme and port are not provided, default to 443 - return host + ":443"; } /** @@ -845,7 +841,7 @@ private String normalizeEndpoint(String host) { public String getResolvedApiaryHost(String serviceName) { String resolvedUniverseDomain = getUniverseDomain() != null ? getUniverseDomain() : Credentials.GOOGLE_DEFAULT_UNIVERSE; - return "https://" + serviceName + "." + resolvedUniverseDomain + "/"; + return "https://www." + serviceName + "." + resolvedUniverseDomain + "/"; } /** Validates that Credentials' Universe Domain matches the user configured Universe Domain. */ diff --git a/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java b/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java index 16dfc28d54..d4e63131ff 100644 --- a/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java +++ b/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java @@ -549,7 +549,7 @@ public void testGetResolvedEndpoint_customUniverseDomain_customHost() { public void testGetResolvedApiaryHost_noUniverseDomain() { TestServiceOptions options = TestServiceOptions.newBuilder().setProjectId("project-id").build(); assertThat(options.getResolvedApiaryHost("service")) - .isEqualTo("https://service.googleapis.com/"); + .isEqualTo("https://www.service.googleapis.com/"); } @Test @@ -560,7 +560,7 @@ public void testGetResolvedApiaryHost_customUniverseDomain_noHost() { .setHost(null) .setProjectId("project-id") .build(); - assertThat(options.getResolvedApiaryHost("service")).isEqualTo("https://service.test.com/"); + assertThat(options.getResolvedApiaryHost("service")).isEqualTo("https://www.service.test.com/"); } @Test @@ -571,12 +571,12 @@ public void testGetResolvedApiaryHost_customUniverseDomain_customHost() { .setHost("https://service.random.com") .setProjectId("project-id") .build(); - assertThat(options.getResolvedApiaryHost("service")).isEqualTo("https://service.test.com/"); + assertThat(options.getResolvedApiaryHost("service")).isEqualTo("https://www.service.test.com/"); } // No User Configuration = GDU, Default Credentials = GDU @Test - public void testisValidUniverseDomain_noUserUniverseDomainConfig_defaultCredentials() + public void testIsValidUniverseDomain_noUserUniverseDomainConfig_defaultCredentials() throws IOException { TestServiceOptions options = TestServiceOptions.newBuilder() @@ -590,7 +590,7 @@ public void testisValidUniverseDomain_noUserUniverseDomainConfig_defaultCredenti // No User Configuration = GDU, non Default Credentials = random.com // non-GDU Credentials could be any domain, the tests use random.com @Test - public void testisValidUniverseDomain_noUserUniverseDomainConfig_nonGDUCredentials() + public void testIsValidUniverseDomain_noUserUniverseDomainConfig_nonGDUCredentials() throws IOException { TestServiceOptions options = TestServiceOptions.newBuilder() @@ -604,7 +604,7 @@ public void testisValidUniverseDomain_noUserUniverseDomainConfig_nonGDUCredentia // User Configuration = random.com, Default Credentials = GDU // User Credentials could be set to any domain, the tests use random.com @Test - public void testisValidUniverseDomain_userUniverseDomainConfig_defaultCredentials() + public void testIsValidUniverseDomain_userUniverseDomainConfig_defaultCredentials() throws IOException { TestServiceOptions options = TestServiceOptions.newBuilder() @@ -620,7 +620,7 @@ public void testisValidUniverseDomain_userUniverseDomainConfig_defaultCredential // User Credentials and non GDU Credentials could be set to any domain, // the tests use random.com @Test - public void testisValidUniverseDomain_userUniverseDomainConfig_nonGDUCredentials() + public void testIsValidUniverseDomain_userUniverseDomainConfig_nonGDUCredentials() throws IOException { TestServiceOptions options = TestServiceOptions.newBuilder() @@ -632,6 +632,57 @@ public void testisValidUniverseDomain_userUniverseDomainConfig_nonGDUCredentials assertThat(options.isValidUniverseDomain()).isTrue(); } + @Test + public void testNormalizeEndpoint_httpEndpoint() { + TestServiceOptions options = + TestServiceOptions.newBuilder() + .setHost("http://test.com") + .setProjectId("project-id") + .build(); + assertThat(options.normalizeEndpoint()).isEqualTo("test.com:80"); + } + + // gRPC-Java is fine to build a channel with `www.` + @Test + public void testNormalizeEndpoint_httpEndpoint_hasWWW() { + TestServiceOptions options = + TestServiceOptions.newBuilder() + .setHost("http://www.test.com") + .setProjectId("project-id") + .build(); + assertThat(options.normalizeEndpoint()).isEqualTo("www.test.com:80"); + } + + @Test + public void testNormalizeEndpoint_httpsEndpoint() { + TestServiceOptions options = + TestServiceOptions.newBuilder() + .setHost("https://test.com") + .setProjectId("project-id") + .build(); + assertThat(options.normalizeEndpoint()).isEqualTo("test.com:443"); + } + + // gRPC-Java is fine to build a channel with `www.` + @Test + public void testNormalizeEndpoint_httpsEndpoint_hasWWW() { + TestServiceOptions options = + TestServiceOptions.newBuilder() + .setHost("https://www.test.com") + .setProjectId("project-id") + .build(); + assertThat(options.normalizeEndpoint()).isEqualTo("www.test.com:443"); + } + + @Test + public void testNormalizeEndpoint_invalidHost() { + TestServiceOptions options = + TestServiceOptions.newBuilder().setHost("test.com:443").setProjectId("project-id").build(); + RuntimeException exception = assertThrows(RuntimeException.class, options::normalizeEndpoint); + assertThat(exception.getMessage()) + .isEqualTo("Invalid host: test.com:443. Expecting http(s)://{domain}"); + } + private HttpResponse createHttpResponseWithHeader(final Multimap headers) throws Exception { HttpTransport mockHttpTransport = From acb94a85c42713381c545753ad48ec8dd483b591 Mon Sep 17 00:00:00 2001 From: Lawrence Qiu Date: Wed, 3 Jan 2024 21:11:57 -0500 Subject: [PATCH 12/21] chore: Address PR comments --- .../java/com/google/cloud/ServiceOptions.java | 47 +++++-------- .../com/google/cloud/ServiceOptionsTest.java | 66 ++----------------- 2 files changed, 22 insertions(+), 91 deletions(-) diff --git a/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java b/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java index 9e638a32d9..c5970ba65a 100644 --- a/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java +++ b/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java @@ -59,7 +59,6 @@ import java.io.InputStream; import java.io.ObjectInputStream; import java.io.Serializable; -import java.net.URI; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.Locale; @@ -798,38 +797,20 @@ public String getQuotaProjectId() { * *

The resolved endpoint is always in `host:port` format */ - public String getResolvedEndpoint(String serviceName) { - if (universeDomain == null) { - return formatEndpoint(serviceName, Credentials.GOOGLE_DEFAULT_UNIVERSE); - } else if (universeDomain.isEmpty()) { + @InternalApi + public String getResolvedHost(String serviceName) { + if (universeDomain != null && universeDomain.isEmpty()) { throw new IllegalArgumentException("Universe Domain cannot be empty"); - } else { - if (host != null) { - return normalizeEndpoint(); - } - return formatEndpoint(serviceName, getUniverseDomain()); } - } - - private String formatEndpoint(String serviceName, String universeDomain) { - return serviceName + "." + universeDomain + ":443"; - } - - // Best effort endpoint normalization to ensure it results in {domain}:{port} format - // for gRPC-Java. `host` is expected to be in format of http(s)://{domain} - String normalizeEndpoint() { - URI uri = URI.create(host); - String scheme = uri.getScheme(); - int port = uri.getPort(); - - // If no port is provided, http:// defaults to 80 and https:// defaults to 443 - if (scheme.equals("http")) { - return String.format("%s:%s", uri.getHost(), port > 0 ? port : 80); - } else if (scheme.equals("https")) { - return String.format("%s:%s", uri.getHost(), port > 0 ? port : 443); - } else { - throw new RuntimeException("Invalid host: " + host + ". Expecting http(s)://{domain}"); + String resolvedUniverseDomain = + universeDomain != null ? universeDomain : Credentials.GOOGLE_DEFAULT_UNIVERSE; + // The host value set to DEFAULT_HOST if the user didn't configure a host. If the + // user set a host the library uses that value, otherwise, construct the host for the user. + // The DEFAULT_HOST value is not a valid host for handwritten libraries. + if (!host.equals(DEFAULT_HOST)) { + return host; } + return "https://www." + serviceName + "." + resolvedUniverseDomain + "/"; } /** @@ -844,7 +825,11 @@ public String getResolvedApiaryHost(String serviceName) { return "https://www." + serviceName + "." + resolvedUniverseDomain + "/"; } - /** Validates that Credentials' Universe Domain matches the user configured Universe Domain. */ + /** + * Validates that Credentials' Universe Domain matches the user configured Universe Domain. + * Currently, this is intended for BigQuery and Storage Apiary Wrapped Libraries + */ + @InternalApi public boolean isValidUniverseDomain() throws IOException { String resolvedUniverseDomain = getUniverseDomain() != null ? getUniverseDomain() : Credentials.GOOGLE_DEFAULT_UNIVERSE; diff --git a/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java b/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java index d4e63131ff..4f1afd7521 100644 --- a/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java +++ b/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java @@ -509,7 +509,7 @@ public void testResponseHeaderDoesNotContainMetaDataFlavor() throws Exception { @Test public void testGetResolvedEndpoint_noUniverseDomain() { TestServiceOptions options = TestServiceOptions.newBuilder().setProjectId("project-id").build(); - assertThat(options.getResolvedEndpoint("service")).isEqualTo("service.googleapis.com:443"); + assertThat(options.getResolvedHost("service")).isEqualTo("https://www.service.googleapis.com/"); } @Test @@ -517,21 +517,18 @@ public void testGetResolvedEndpoint_emptyUniverseDomain() { TestServiceOptions options = TestServiceOptions.newBuilder().setUniverseDomain("").setProjectId("project-id").build(); IllegalArgumentException exception = - assertThrows(IllegalArgumentException.class, () -> options.getResolvedEndpoint("service")); + assertThrows(IllegalArgumentException.class, () -> options.getResolvedHost("service")); assertThat(exception.getMessage()).isEqualTo("Universe Domain cannot be empty"); } @Test - public void testGetResolvedEndpoint_customUniverseDomain_noHost() { + public void testGetResolvedEndpoint_customUniverseDomain() { TestServiceOptions options = TestServiceOptions.newBuilder() .setUniverseDomain("test.com") - .setHost(null) .setProjectId("project-id") .build(); - // `https://www.googleapis.com` is the DEFAULT_HOST value for ServiceOptions. The ServiceOptions - // builder will set as it as the host if host is null - assertThat(options.getResolvedEndpoint("service")).isEqualTo("www.googleapis.com:443"); + assertThat(options.getResolvedHost("service")).isEqualTo("https://www.service.test.com/"); } @Test @@ -539,10 +536,10 @@ public void testGetResolvedEndpoint_customUniverseDomain_customHost() { TestServiceOptions options = TestServiceOptions.newBuilder() .setUniverseDomain("test.com") - .setHost("https://service.random.com") + .setHost("https://www.service.random.com/") .setProjectId("project-id") .build(); - assertThat(options.getResolvedEndpoint("service")).isEqualTo("service.random.com:443"); + assertThat(options.getResolvedHost("service")).isEqualTo("https://www.service.random.com/"); } @Test @@ -632,57 +629,6 @@ public void testIsValidUniverseDomain_userUniverseDomainConfig_nonGDUCredentials assertThat(options.isValidUniverseDomain()).isTrue(); } - @Test - public void testNormalizeEndpoint_httpEndpoint() { - TestServiceOptions options = - TestServiceOptions.newBuilder() - .setHost("http://test.com") - .setProjectId("project-id") - .build(); - assertThat(options.normalizeEndpoint()).isEqualTo("test.com:80"); - } - - // gRPC-Java is fine to build a channel with `www.` - @Test - public void testNormalizeEndpoint_httpEndpoint_hasWWW() { - TestServiceOptions options = - TestServiceOptions.newBuilder() - .setHost("http://www.test.com") - .setProjectId("project-id") - .build(); - assertThat(options.normalizeEndpoint()).isEqualTo("www.test.com:80"); - } - - @Test - public void testNormalizeEndpoint_httpsEndpoint() { - TestServiceOptions options = - TestServiceOptions.newBuilder() - .setHost("https://test.com") - .setProjectId("project-id") - .build(); - assertThat(options.normalizeEndpoint()).isEqualTo("test.com:443"); - } - - // gRPC-Java is fine to build a channel with `www.` - @Test - public void testNormalizeEndpoint_httpsEndpoint_hasWWW() { - TestServiceOptions options = - TestServiceOptions.newBuilder() - .setHost("https://www.test.com") - .setProjectId("project-id") - .build(); - assertThat(options.normalizeEndpoint()).isEqualTo("www.test.com:443"); - } - - @Test - public void testNormalizeEndpoint_invalidHost() { - TestServiceOptions options = - TestServiceOptions.newBuilder().setHost("test.com:443").setProjectId("project-id").build(); - RuntimeException exception = assertThrows(RuntimeException.class, options::normalizeEndpoint); - assertThat(exception.getMessage()) - .isEqualTo("Invalid host: test.com:443. Expecting http(s)://{domain}"); - } - private HttpResponse createHttpResponseWithHeader(final Multimap headers) throws Exception { HttpTransport mockHttpTransport = From f4eaad38e4aeaa68869656c55404d2b9e6d40db9 Mon Sep 17 00:00:00 2001 From: Lawrence Qiu Date: Thu, 4 Jan 2024 10:53:42 -0500 Subject: [PATCH 13/21] chore: Address PR comments --- .../java/com/google/cloud/ServiceOptions.java | 43 +++++++++++-------- .../com/google/cloud/ServiceOptionsTest.java | 8 ++-- 2 files changed, 30 insertions(+), 21 deletions(-) diff --git a/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java b/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java index c5970ba65a..fe9cfd173e 100644 --- a/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java +++ b/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java @@ -202,13 +202,18 @@ public B setHost(String host) { } /** - * Universe Domain is the domain for Google Cloud Services. It follows the format of - * `{ServiceName}.{UniverseDomain}`. For example, speech.googleapis.com would have a Universe - * Domain value of `googleapis.com` and cloudasset.test.com would have a Universe Domain of - * `test.com`. If this value is not set, this will default to `googleapis.com`. + * Universe Domain is the domain for Google Cloud Services. A Google Cloud endpoint follows the + * format of `{ServiceName}.{UniverseDomain}`. For example, speech.googleapis.com would have a + * Universe Domain value of `googleapis.com` and cloudasset.test.com would have a Universe + * Domain of `test.com`. + * + *

If this value is not set, the resolved UniverseDomain will default to `googleapis.com`. + * + * @throws NullPointerException if {@code universeDomain} is {@code null}. The resolved + * universeDomain will be `googleapis.com` if this value is not set. */ public B setUniverseDomain(String universeDomain) { - this.universeDomain = universeDomain; + this.universeDomain = checkNotNull(universeDomain); return self(); } @@ -597,10 +602,13 @@ public String getProjectId() { } /** - * Universe Domain is the domain for Google Cloud Services. It follows the format of - * `{ServiceName}.{UniverseDomain}`. For example, speech.googleapis.com would have a Universe - * Domain value of `googleapis.com` and cloudasset.test.com would have a Universe Domain of - * `test.com`. If this value is not set, this will default to `googleapis.com`. + * Universe Domain is the domain for Google Cloud Services. A Google Cloud endpoint follows the + * format of `{ServiceName}.{UniverseDomain}`. For example, speech.googleapis.com would have a + * Universe Domain value of `googleapis.com` and cloudasset.test.com would have a Universe Domain + * of `test.com`. + * + * @return The universe domain value set in the Builder's setter. Does not return the resolved + * Universe Domain */ public String getUniverseDomain() { return universeDomain; @@ -793,9 +801,10 @@ public String getQuotaProjectId() { } /** - * Returns the resolved endpoint for the Service to connect to Google Cloud + * Returns the resolved host for the Service to connect to Google Cloud * - *

The resolved endpoint is always in `host:port` format + *

The resolved host will be in `https://www.{serviceName}.{resolvedUniverseDomain}/` format. + * The resolvedUniverseDomain will be set to `googleapis.com` if universeDomain is null. */ @InternalApi public String getResolvedHost(String serviceName) { @@ -816,23 +825,23 @@ public String getResolvedHost(String serviceName) { /** * Temporarily used for BigQuery and Storage Apiary Wrapped Libraries. To be removed in the * future. Returns the host to be used for the rootUrl and output is in the format of: - * "https://serviceName.universeDomain/" + * "https://www.serviceName.universeDomain/" */ @InternalApi public String getResolvedApiaryHost(String serviceName) { String resolvedUniverseDomain = - getUniverseDomain() != null ? getUniverseDomain() : Credentials.GOOGLE_DEFAULT_UNIVERSE; + universeDomain != null ? universeDomain : Credentials.GOOGLE_DEFAULT_UNIVERSE; return "https://www." + serviceName + "." + resolvedUniverseDomain + "/"; } /** - * Validates that Credentials' Universe Domain matches the user configured Universe Domain. - * Currently, this is intended for BigQuery and Storage Apiary Wrapped Libraries + * Validates that Credentials' Universe Domain matches the resolved Universe Domain. Currently, + * this is intended for BigQuery and Storage Apiary Wrapped Libraries */ @InternalApi - public boolean isValidUniverseDomain() throws IOException { + public boolean hasValidUniverseDomain() throws IOException { String resolvedUniverseDomain = - getUniverseDomain() != null ? getUniverseDomain() : Credentials.GOOGLE_DEFAULT_UNIVERSE; + universeDomain != null ? universeDomain : Credentials.GOOGLE_DEFAULT_UNIVERSE; return resolvedUniverseDomain.equals(getCredentials().getUniverseDomain()); } } diff --git a/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java b/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java index 4f1afd7521..1d597eec23 100644 --- a/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java +++ b/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java @@ -581,7 +581,7 @@ public void testIsValidUniverseDomain_noUserUniverseDomainConfig_defaultCredenti .setHost("https://test.random.com") .setCredentials(credentials) .build(); - assertThat(options.isValidUniverseDomain()).isTrue(); + assertThat(options.hasValidUniverseDomain()).isTrue(); } // No User Configuration = GDU, non Default Credentials = random.com @@ -595,7 +595,7 @@ public void testIsValidUniverseDomain_noUserUniverseDomainConfig_nonGDUCredentia .setHost("https://test.random.com") .setCredentials(credentialsNotInGDU) .build(); - assertThat(options.isValidUniverseDomain()).isFalse(); + assertThat(options.hasValidUniverseDomain()).isFalse(); } // User Configuration = random.com, Default Credentials = GDU @@ -610,7 +610,7 @@ public void testIsValidUniverseDomain_userUniverseDomainConfig_defaultCredential .setUniverseDomain("random.com") .setCredentials(credentials) .build(); - assertThat(options.isValidUniverseDomain()).isFalse(); + assertThat(options.hasValidUniverseDomain()).isFalse(); } // User Configuration = random.com, non Default Credentials = random.com @@ -626,7 +626,7 @@ public void testIsValidUniverseDomain_userUniverseDomainConfig_nonGDUCredentials .setUniverseDomain("random.com") .setCredentials(credentialsNotInGDU) .build(); - assertThat(options.isValidUniverseDomain()).isTrue(); + assertThat(options.hasValidUniverseDomain()).isTrue(); } private HttpResponse createHttpResponseWithHeader(final Multimap headers) From 6709f2c87ff8d7e5661bd8223c1b08891ed7c153 Mon Sep 17 00:00:00 2001 From: Lawrence Qiu Date: Thu, 4 Jan 2024 11:01:24 -0500 Subject: [PATCH 14/21] chore: Fix comments --- .../main/java/com/google/cloud/ServiceOptions.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java b/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java index fe9cfd173e..ce44611cda 100644 --- a/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java +++ b/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java @@ -607,7 +607,7 @@ public String getProjectId() { * Universe Domain value of `googleapis.com` and cloudasset.test.com would have a Universe Domain * of `test.com`. * - * @return The universe domain value set in the Builder's setter. Does not return the resolved + * @return The universe domain value set in the Builder's setter. This is not the resolved * Universe Domain */ public String getUniverseDomain() { @@ -815,7 +815,8 @@ public String getResolvedHost(String serviceName) { universeDomain != null ? universeDomain : Credentials.GOOGLE_DEFAULT_UNIVERSE; // The host value set to DEFAULT_HOST if the user didn't configure a host. If the // user set a host the library uses that value, otherwise, construct the host for the user. - // The DEFAULT_HOST value is not a valid host for handwritten libraries. + // The DEFAULT_HOST value is not a valid host for handwritten libraries and should be + // overriden to include the serviceName. if (!host.equals(DEFAULT_HOST)) { return host; } @@ -824,8 +825,10 @@ public String getResolvedHost(String serviceName) { /** * Temporarily used for BigQuery and Storage Apiary Wrapped Libraries. To be removed in the - * future. Returns the host to be used for the rootUrl and output is in the format of: - * "https://www.serviceName.universeDomain/" + * future. Returns the host to be used as the rootUrl. + * + *

The resolved host will be in `https://www.{serviceName}.{resolvedUniverseDomain}/` format. + * The resolvedUniverseDomain will be set to `googleapis.com` if universeDomain is null. */ @InternalApi public String getResolvedApiaryHost(String serviceName) { @@ -836,7 +839,7 @@ public String getResolvedApiaryHost(String serviceName) { /** * Validates that Credentials' Universe Domain matches the resolved Universe Domain. Currently, - * this is intended for BigQuery and Storage Apiary Wrapped Libraries + * this is only intended for BigQuery and Storage Apiary Wrapped Libraries */ @InternalApi public boolean hasValidUniverseDomain() throws IOException { From ac02baf65271243c5725df15d7ca7568d0486d58 Mon Sep 17 00:00:00 2001 From: Lawrence Qiu Date: Thu, 4 Jan 2024 12:11:56 -0500 Subject: [PATCH 15/21] chore: Address PR comments --- gapic-generator-java-pom-parent/pom.xml | 2 +- .../main/java/com/google/cloud/ServiceOptions.java | 14 +++++++++----- .../java/com/google/cloud/ServiceOptionsTest.java | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/gapic-generator-java-pom-parent/pom.xml b/gapic-generator-java-pom-parent/pom.xml index 4cd0a2f8f1..3b48987efd 100644 --- a/gapic-generator-java-pom-parent/pom.xml +++ b/gapic-generator-java-pom-parent/pom.xml @@ -27,7 +27,7 @@ consistent across modules in this repository --> 1.3.2 1.60.0 - 1.21.0 + 1.20.0 1.43.3 2.10.1 32.1.3-jre diff --git a/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java b/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java index ce44611cda..4c0bcd10e8 100644 --- a/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java +++ b/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java @@ -809,7 +809,7 @@ public String getQuotaProjectId() { @InternalApi public String getResolvedHost(String serviceName) { if (universeDomain != null && universeDomain.isEmpty()) { - throw new IllegalArgumentException("Universe Domain cannot be empty"); + throw new IllegalArgumentException("The universe domain cannot be empty"); } String resolvedUniverseDomain = universeDomain != null ? universeDomain : Credentials.GOOGLE_DEFAULT_UNIVERSE; @@ -817,15 +817,16 @@ public String getResolvedHost(String serviceName) { // user set a host the library uses that value, otherwise, construct the host for the user. // The DEFAULT_HOST value is not a valid host for handwritten libraries and should be // overriden to include the serviceName. - if (!host.equals(DEFAULT_HOST)) { + if (!DEFAULT_HOST.equals(host)) { return host; } return "https://www." + serviceName + "." + resolvedUniverseDomain + "/"; } /** - * Temporarily used for BigQuery and Storage Apiary Wrapped Libraries. To be removed in the - * future. Returns the host to be used as the rootUrl. + * Temporarily used for BigQuery and Storage Apiary Wrapped Libraries. To be removed in the future + * when Apiary clients can resolve the endpoints. Returns the host to be used as the {@see rootUrl} * *

The resolved host will be in `https://www.{serviceName}.{resolvedUniverseDomain}/` format. * The resolvedUniverseDomain will be set to `googleapis.com` if universeDomain is null. @@ -839,7 +840,10 @@ public String getResolvedApiaryHost(String serviceName) { /** * Validates that Credentials' Universe Domain matches the resolved Universe Domain. Currently, - * this is only intended for BigQuery and Storage Apiary Wrapped Libraries + * this is only intended for BigQuery and Storage Apiary Wrapped Libraries. + * + *

This validation call should be made prior to Apiary RPCs invocations. If the checks finds + * that there is an invalid universe domain, the call should not be made. */ @InternalApi public boolean hasValidUniverseDomain() throws IOException { diff --git a/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java b/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java index 1d597eec23..4f580525c5 100644 --- a/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java +++ b/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java @@ -518,7 +518,7 @@ public void testGetResolvedEndpoint_emptyUniverseDomain() { TestServiceOptions.newBuilder().setUniverseDomain("").setProjectId("project-id").build(); IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> options.getResolvedHost("service")); - assertThat(exception.getMessage()).isEqualTo("Universe Domain cannot be empty"); + assertThat(exception.getMessage()).isEqualTo("The universe domain cannot be empty"); } @Test From 793211ccdc8fd6cab8edd1c9227fc50aec5f0472 Mon Sep 17 00:00:00 2001 From: Lawrence Qiu Date: Thu, 4 Jan 2024 12:27:35 -0500 Subject: [PATCH 16/21] chore: Address PR comments --- .../src/main/java/com/google/cloud/ServiceOptions.java | 4 ++-- .../src/test/java/com/google/cloud/ServiceOptionsTest.java | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java b/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java index 4c0bcd10e8..03c321980a 100644 --- a/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java +++ b/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java @@ -825,7 +825,7 @@ public String getResolvedHost(String serviceName) { /** * Temporarily used for BigQuery and Storage Apiary Wrapped Libraries. To be removed in the future - * when Apiary clients can resolve the endpoints. Returns the host to be used as the {@see rootUrl} * *

The resolved host will be in `https://www.{serviceName}.{resolvedUniverseDomain}/` format. @@ -842,7 +842,7 @@ public String getResolvedApiaryHost(String serviceName) { * Validates that Credentials' Universe Domain matches the resolved Universe Domain. Currently, * this is only intended for BigQuery and Storage Apiary Wrapped Libraries. * - *

This validation call should be made prior to Apiary RPCs invocations. If the checks finds + *

This validation call should be made prior to Apiary RPCs invocations. If the checks find * that there is an invalid universe domain, the call should not be made. */ @InternalApi diff --git a/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java b/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java index 4f580525c5..c65637393b 100644 --- a/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java +++ b/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java @@ -148,6 +148,7 @@ public class ServiceOptionsTest { + " \"universe_domain\": \"googleapis.com\"\n" + "}"; + // Key added by copying the keys above and adding in the universe domain field private static final String JSON_KEY_NON_GDU = "{\n" + " \"private_key_id\": \"somekeyid\",\n" From 876b8648118f66c42a3e167f20574049c2c405d6 Mon Sep 17 00:00:00 2001 From: Lawrence Qiu Date: Thu, 4 Jan 2024 13:20:09 -0500 Subject: [PATCH 17/21] chore: Add links --- .../main/java/com/google/cloud/ServiceOptions.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java b/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java index 03c321980a..f0d6e05b26 100644 --- a/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java +++ b/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java @@ -804,7 +804,11 @@ public String getQuotaProjectId() { * Returns the resolved host for the Service to connect to Google Cloud * *

The resolved host will be in `https://www.{serviceName}.{resolvedUniverseDomain}/` format. - * The resolvedUniverseDomain will be set to `googleapis.com` if universeDomain is null. + * The resolvedUniverseDomain will be set to `googleapis.com` if universeDomain is null. The + * format is similar to the DEFAULT_HOST value in java-core. + * + * @see DEFAULT_HOST */ @InternalApi public String getResolvedHost(String serviceName) { @@ -825,11 +829,13 @@ public String getResolvedHost(String serviceName) { /** * Temporarily used for BigQuery and Storage Apiary Wrapped Libraries. To be removed in the future - * when Apiary clients can resolve their endpoints. Returns the host to be used as the {@see rootUrl} + * when Apiary clients can resolve their endpoints. Returns the host to be used as the rootUrl. * *

The resolved host will be in `https://www.{serviceName}.{resolvedUniverseDomain}/` format. * The resolvedUniverseDomain will be set to `googleapis.com` if universeDomain is null. + * + * @see rootUrl */ @InternalApi public String getResolvedApiaryHost(String serviceName) { From a6f32348d551d83eb14dca738d7b6c3f57b3daf7 Mon Sep 17 00:00:00 2001 From: Lawrence Qiu Date: Thu, 4 Jan 2024 13:22:15 -0500 Subject: [PATCH 18/21] chore: Add format to match DEFAULT_HOST --- .../src/main/java/com/google/cloud/ServiceOptions.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java b/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java index f0d6e05b26..f47106f371 100644 --- a/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java +++ b/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java @@ -803,7 +803,7 @@ public String getQuotaProjectId() { /** * Returns the resolved host for the Service to connect to Google Cloud * - *

The resolved host will be in `https://www.{serviceName}.{resolvedUniverseDomain}/` format. + *

The resolved host will be in `https://www.{serviceName}.{resolvedUniverseDomain}` format. * The resolvedUniverseDomain will be set to `googleapis.com` if universeDomain is null. The * format is similar to the DEFAULT_HOST value in java-core. * @@ -824,7 +824,7 @@ public String getResolvedHost(String serviceName) { if (!DEFAULT_HOST.equals(host)) { return host; } - return "https://www." + serviceName + "." + resolvedUniverseDomain + "/"; + return "https://www." + serviceName + "." + resolvedUniverseDomain; } /** From 73db273814e11a81c05bd6c0ac527a99c8d58127 Mon Sep 17 00:00:00 2001 From: Lawrence Qiu Date: Thu, 4 Jan 2024 13:26:42 -0500 Subject: [PATCH 19/21] chore: Fix failing tests --- .../src/test/java/com/google/cloud/ServiceOptionsTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java b/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java index c65637393b..ad2ceab17a 100644 --- a/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java +++ b/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java @@ -510,7 +510,7 @@ public void testResponseHeaderDoesNotContainMetaDataFlavor() throws Exception { @Test public void testGetResolvedEndpoint_noUniverseDomain() { TestServiceOptions options = TestServiceOptions.newBuilder().setProjectId("project-id").build(); - assertThat(options.getResolvedHost("service")).isEqualTo("https://www.service.googleapis.com/"); + assertThat(options.getResolvedHost("service")).isEqualTo("https://www.service.googleapis.com"); } @Test @@ -529,7 +529,7 @@ public void testGetResolvedEndpoint_customUniverseDomain() { .setUniverseDomain("test.com") .setProjectId("project-id") .build(); - assertThat(options.getResolvedHost("service")).isEqualTo("https://www.service.test.com/"); + assertThat(options.getResolvedHost("service")).isEqualTo("https://www.service.test.com"); } @Test From 60c096b80c1e643a82c3472f48e6b56927b546d2 Mon Sep 17 00:00:00 2001 From: Lawrence Qiu Date: Thu, 4 Jan 2024 13:29:47 -0500 Subject: [PATCH 20/21] chore: Update javadocs --- .../src/main/java/com/google/cloud/ServiceOptions.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java b/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java index f47106f371..26ba572137 100644 --- a/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java +++ b/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java @@ -848,8 +848,8 @@ public String getResolvedApiaryHost(String serviceName) { * Validates that Credentials' Universe Domain matches the resolved Universe Domain. Currently, * this is only intended for BigQuery and Storage Apiary Wrapped Libraries. * - *

This validation call should be made prior to Apiary RPCs invocations. If the checks find - * that there is an invalid universe domain, the call should not be made. + *

This validation call should be made prior to any RPC invocation. This call is used to gate + * the RPC invocation if there is no valid universe domain. */ @InternalApi public boolean hasValidUniverseDomain() throws IOException { From f63e8cd1e4ff5251189adb959ae3e654507bee92 Mon Sep 17 00:00:00 2001 From: Lawrence Qiu Date: Thu, 4 Jan 2024 14:06:39 -0500 Subject: [PATCH 21/21] chore: Remove www. prefix --- .../main/java/com/google/cloud/ServiceOptions.java | 14 +++++++------- .../java/com/google/cloud/ServiceOptionsTest.java | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java b/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java index 26ba572137..16879b8914 100644 --- a/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java +++ b/java-core/google-cloud-core/src/main/java/com/google/cloud/ServiceOptions.java @@ -803,9 +803,9 @@ public String getQuotaProjectId() { /** * Returns the resolved host for the Service to connect to Google Cloud * - *

The resolved host will be in `https://www.{serviceName}.{resolvedUniverseDomain}` format. - * The resolvedUniverseDomain will be set to `googleapis.com` if universeDomain is null. The - * format is similar to the DEFAULT_HOST value in java-core. + *

The resolved host will be in `https://{serviceName}.{resolvedUniverseDomain}` format. The + * resolvedUniverseDomain will be set to `googleapis.com` if universeDomain is null. The format is + * similar to the DEFAULT_HOST value in java-core. * * @see DEFAULT_HOST @@ -824,15 +824,15 @@ public String getResolvedHost(String serviceName) { if (!DEFAULT_HOST.equals(host)) { return host; } - return "https://www." + serviceName + "." + resolvedUniverseDomain; + return "https://" + serviceName + "." + resolvedUniverseDomain; } /** * Temporarily used for BigQuery and Storage Apiary Wrapped Libraries. To be removed in the future * when Apiary clients can resolve their endpoints. Returns the host to be used as the rootUrl. * - *

The resolved host will be in `https://www.{serviceName}.{resolvedUniverseDomain}/` format. - * The resolvedUniverseDomain will be set to `googleapis.com` if universeDomain is null. + *

The resolved host will be in `https://{serviceName}.{resolvedUniverseDomain}/` format. The + * resolvedUniverseDomain will be set to `googleapis.com` if universeDomain is null. * * @see rootUrl @@ -841,7 +841,7 @@ public String getResolvedHost(String serviceName) { public String getResolvedApiaryHost(String serviceName) { String resolvedUniverseDomain = universeDomain != null ? universeDomain : Credentials.GOOGLE_DEFAULT_UNIVERSE; - return "https://www." + serviceName + "." + resolvedUniverseDomain + "/"; + return "https://" + serviceName + "." + resolvedUniverseDomain + "/"; } /** diff --git a/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java b/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java index ad2ceab17a..3d5ca3eef5 100644 --- a/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java +++ b/java-core/google-cloud-core/src/test/java/com/google/cloud/ServiceOptionsTest.java @@ -510,7 +510,7 @@ public void testResponseHeaderDoesNotContainMetaDataFlavor() throws Exception { @Test public void testGetResolvedEndpoint_noUniverseDomain() { TestServiceOptions options = TestServiceOptions.newBuilder().setProjectId("project-id").build(); - assertThat(options.getResolvedHost("service")).isEqualTo("https://www.service.googleapis.com"); + assertThat(options.getResolvedHost("service")).isEqualTo("https://service.googleapis.com"); } @Test @@ -529,7 +529,7 @@ public void testGetResolvedEndpoint_customUniverseDomain() { .setUniverseDomain("test.com") .setProjectId("project-id") .build(); - assertThat(options.getResolvedHost("service")).isEqualTo("https://www.service.test.com"); + assertThat(options.getResolvedHost("service")).isEqualTo("https://service.test.com"); } @Test @@ -537,17 +537,17 @@ public void testGetResolvedEndpoint_customUniverseDomain_customHost() { TestServiceOptions options = TestServiceOptions.newBuilder() .setUniverseDomain("test.com") - .setHost("https://www.service.random.com/") + .setHost("https://service.random.com/") .setProjectId("project-id") .build(); - assertThat(options.getResolvedHost("service")).isEqualTo("https://www.service.random.com/"); + assertThat(options.getResolvedHost("service")).isEqualTo("https://service.random.com/"); } @Test public void testGetResolvedApiaryHost_noUniverseDomain() { TestServiceOptions options = TestServiceOptions.newBuilder().setProjectId("project-id").build(); assertThat(options.getResolvedApiaryHost("service")) - .isEqualTo("https://www.service.googleapis.com/"); + .isEqualTo("https://service.googleapis.com/"); } @Test @@ -558,7 +558,7 @@ public void testGetResolvedApiaryHost_customUniverseDomain_noHost() { .setHost(null) .setProjectId("project-id") .build(); - assertThat(options.getResolvedApiaryHost("service")).isEqualTo("https://www.service.test.com/"); + assertThat(options.getResolvedApiaryHost("service")).isEqualTo("https://service.test.com/"); } @Test @@ -569,7 +569,7 @@ public void testGetResolvedApiaryHost_customUniverseDomain_customHost() { .setHost("https://service.random.com") .setProjectId("project-id") .build(); - assertThat(options.getResolvedApiaryHost("service")).isEqualTo("https://www.service.test.com/"); + assertThat(options.getResolvedApiaryHost("service")).isEqualTo("https://service.test.com/"); } // No User Configuration = GDU, Default Credentials = GDU