Skip to content

Commit

Permalink
feat: Parse Host Service Name (#2300)
Browse files Browse the repository at this point in the history
* refactor: Add transportchannelprovider's endpoint to EndpointContext

* chore: Add Endpoint tests for ClientContext

* chore: Resolve PR comments

* feat: Add HostServiceName to StubSettings

* chore: Add comments for hostservicename

* chore: Fix setEndpoint logic

* chore: Add InternalApi annotation to setDefaultHost in StubSettings

* fix: Expose HostServiceName in ClientContext

* chore: Add comments for hostservicename

* chore: Set hostServiceName to package private scope

* chore: Update integration tests

* chore: Resolve PR comments

* chore: Do not generate getServiceName if hostServiceName is empty

* chore: Add tests for parsing Host Service Name
  • Loading branch information
lqiu96 committed Dec 18, 2023
1 parent f8969d2 commit 8822f3b
Show file tree
Hide file tree
Showing 27 changed files with 211 additions and 1 deletion.
Expand Up @@ -57,6 +57,9 @@ public class SettingsCommentComposer {

public static final CommentStatement DEFAULT_EXECUTOR_PROVIDER_BUILDER_METHOD_COMMENT =
toSimpleComment("Returns a builder for the default ExecutorProvider for this service.");

public static final CommentStatement DEFAULT_SERVICE_NAME_METHOD_COMMENT =
toSimpleComment("Returns the default service name.");
public static final CommentStatement DEFAULT_SERVICE_ENDPOINT_METHOD_COMMENT =
toSimpleComment("Returns the default service endpoint.");
public static final CommentStatement DEFAULT_SERVICE_MTLS_ENDPOINT_METHOD_COMMENT =
Expand Down
Expand Up @@ -97,6 +97,7 @@
import com.google.api.generator.gapic.model.Service;
import com.google.api.generator.gapic.utils.JavaStyle;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
Expand Down Expand Up @@ -1137,9 +1138,27 @@ private MethodDefinition createCreateStubMethod(Service service, TypeStore typeS
private List<MethodDefinition> createDefaultHelperAndGetterMethods(
Service service, TypeStore typeStore) {
List<MethodDefinition> javaMethods = new ArrayList<>();
TypeNode returnType;

// Create the getServiceName method.
if (!Strings.isNullOrEmpty(service.hostServiceName())) {
returnType = TypeNode.STRING;
javaMethods.add(
MethodDefinition.builder()
.setHeaderCommentStatements(
SettingsCommentComposer.DEFAULT_SERVICE_NAME_METHOD_COMMENT)
.setIsOverride(true)
.setScope(ScopeNode.PUBLIC)
.setIsStatic(false)
.setReturnType(returnType)
.setName("getServiceName")
.setReturnExpr(
ValueExpr.withValue(StringObjectValue.withValue(service.hostServiceName())))
.build());
}

// Create the defaultExecutorProviderBuilder method.
TypeNode returnType =
returnType =
TypeNode.withReference(
ConcreteReference.withClazz(InstantiatingExecutorProvider.Builder.class));
javaMethods.add(
Expand Down
Expand Up @@ -52,6 +52,12 @@ public boolean hasDescription() {
return !Strings.isNullOrEmpty(description());
}

public String hostServiceName() {
// Host Service Name is guaranteed to exist and be non-null and non-empty
// Parser will fail if the default host is not supplied
return parseHostServiceName(defaultHost());
}

public String apiShortName() {
if (!Strings.isNullOrEmpty(defaultHost())) {
return parseApiShortName(defaultHost());
Expand Down Expand Up @@ -184,6 +190,17 @@ private static String parseApiVersion(String protoPackage) {
return apiVersion;
}

// Parse the service name from the default host configured in the protos
// or service yaml file. For Google Cloud Services, the default host value
// is expected to contain `.googleapis.com`. Exceptions may exist (i.e. localhost),
// in which case we will return an empty string.
private static String parseHostServiceName(String defaultHost) {
if (defaultHost.contains(".googleapis.com")) {
return Iterables.getFirst(Splitter.on(".").split(defaultHost), defaultHost);
}
return "";
}

// Parse defaultHost for apiShortName for the RegionTag. Need to account for regional default
// endpoints like
// "us-east1-pubsub.googleapis.com".
Expand Down
Expand Up @@ -422,6 +422,12 @@ public class LoggingServiceV2StubSettings extends StubSettings<LoggingServiceV2S
"Transport not supported: %s", getTransportChannelProvider().getTransportName()));
}

/** Returns the default service name. */
@Override
public String getServiceName() {
return "logging";
}

/** Returns a builder for the default ExecutorProvider for this service. */
public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder() {
return InstantiatingExecutorProvider.newBuilder();
Expand Down
Expand Up @@ -431,6 +431,12 @@ public class PublisherStubSettings extends StubSettings<PublisherStubSettings> {
"Transport not supported: %s", getTransportChannelProvider().getTransportName()));
}

/** Returns the default service name. */
@Override
public String getServiceName() {
return "pubsub";
}

/** Returns a builder for the default ExecutorProvider for this service. */
public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder() {
return InstantiatingExecutorProvider.newBuilder();
Expand Down
Expand Up @@ -177,4 +177,17 @@ public void hasAnyEnabledMethodsForTransport_shouldThrowExceptionForGRPCRESTTran
Service testService = testServiceBuilder.build();
testService.hasAnyEnabledMethodsForTransport(Transport.GRPC_REST);
}

@Test
public void hostServiceName_googleApisDefaultHost() {
Service service = testServiceBuilder.setDefaultHost("test.googleapis.com").build();
assertThat(service.hostServiceName()).isEqualTo("test");
}

@Test
public void hostServiceName_nonGoogleApisDefaultHost() {
// Default Host is localhost:7469
Service service = testServiceBuilder.build();
assertThat(service.hostServiceName()).isEqualTo("");
}
}
Expand Up @@ -100,6 +100,10 @@ public abstract class ClientContext {
@Nonnull
public abstract Duration getStreamWatchdogCheckInterval();

// Package-Private scope for internal use only. Shared between StubSettings and ClientContext
@Nullable
abstract String getServiceName();

@Nullable
public abstract String getEndpoint();

Expand Down Expand Up @@ -202,6 +206,7 @@ public static ClientContext create(StubSettings settings) throws IOException {
}
EndpointContext endpointContext =
EndpointContext.newBuilder()
.setServiceName(settings.getServiceName())
.setClientSettingsEndpoint(settings.getEndpoint())
.setTransportChannelProviderEndpoint(
settings.getTransportChannelProvider().getEndpoint())
Expand Down Expand Up @@ -258,6 +263,7 @@ public static ClientContext create(StubSettings settings) throws IOException {
.setInternalHeaders(ImmutableMap.copyOf(settings.getInternalHeaderProvider().getHeaders()))
.setClock(clock)
.setDefaultCallContext(defaultCallContext)
.setServiceName(settings.getServiceName())
.setEndpoint(settings.getEndpoint())
.setQuotaProjectId(settings.getQuotaProjectId())
.setStreamWatchdog(watchdog)
Expand Down Expand Up @@ -323,6 +329,9 @@ public abstract static class Builder {

public abstract Builder setDefaultCallContext(ApiCallContext defaultCallContext);

// Package-Private scope for internal use only. Shared between StubSettings and ClientContext
abstract Builder setServiceName(String serviceName);

public abstract Builder setEndpoint(String endpoint);

public abstract Builder setQuotaProjectId(String QuotaProjectId);
Expand Down
Expand Up @@ -40,6 +40,14 @@
@InternalApi
@AutoValue
public abstract class EndpointContext {
/**
* ServiceName is host URI for Google Cloud Services. It follows the format of
* `{ServiceName}.googleapis.com`. For example, speech.googleapis.com would have a ServiceName of
* speech and cloudasset.googleapis.com would have a ServiceName of cloudasset.
*/
@Nullable
public abstract String serviceName();

/**
* ClientSettingsEndpoint is the endpoint value set via the ClientSettings/StubSettings classes.
*/
Expand Down Expand Up @@ -117,6 +125,13 @@ public String getResolvedEndpoint() {

@AutoValue.Builder
public abstract static class Builder {
/**
* ServiceName is host URI for Google Cloud Services. It follows the format of
* `{ServiceName}.googleapis.com`. For example, speech.googleapis.com would have a ServiceName
* of speech and cloudasset.googleapis.com would have a ServiceName of cloudasset.
*/
public abstract Builder setServiceName(String serviceName);

/**
* ClientSettingsEndpoint is the endpoint value set via the ClientSettings/StubSettings classes.
*/
Expand Down
Expand Up @@ -32,6 +32,7 @@
import com.google.api.core.ApiClock;
import com.google.api.core.ApiFunction;
import com.google.api.core.BetaApi;
import com.google.api.core.InternalApi;
import com.google.api.core.NanoClock;
import com.google.api.gax.core.CredentialsProvider;
import com.google.api.gax.core.ExecutorProvider;
Expand Down Expand Up @@ -70,6 +71,7 @@ public abstract class StubSettings<SettingsT extends StubSettings<SettingsT>> {
private final HeaderProvider internalHeaderProvider;
private final TransportChannelProvider transportChannelProvider;
private final ApiClock clock;
private final String serviceName;
private final String endpoint;
private final String mtlsEndpoint;
private final String quotaProjectId;
Expand All @@ -96,6 +98,7 @@ protected StubSettings(Builder builder) {
this.headerProvider = builder.headerProvider;
this.internalHeaderProvider = builder.internalHeaderProvider;
this.clock = builder.clock;
this.serviceName = builder.serviceName;
this.endpoint = builder.endpoint;
this.mtlsEndpoint = builder.mtlsEndpoint;
this.switchToMtlsEndpointAllowed = builder.switchToMtlsEndpointAllowed;
Expand Down Expand Up @@ -137,6 +140,13 @@ public final ApiClock getClock() {
return clock;
}

// Intended for Internal Use and Overriden by generated ServiceStubSettings classes.
// Meant to be shared between StubSettings and ClientContext.
@InternalApi
public String getServiceName() {
return "";
}

public final String getEndpoint() {
return endpoint;
}
Expand Down Expand Up @@ -211,6 +221,7 @@ public abstract static class Builder<
private HeaderProvider internalHeaderProvider;
private TransportChannelProvider transportChannelProvider;
private ApiClock clock;
private String serviceName;
private String endpoint;
private String mtlsEndpoint;
private String quotaProjectId;
Expand All @@ -236,6 +247,7 @@ protected Builder(StubSettings settings) {
this.headerProvider = settings.headerProvider;
this.internalHeaderProvider = settings.internalHeaderProvider;
this.clock = settings.clock;
this.serviceName = settings.serviceName;
this.endpoint = settings.endpoint;
this.mtlsEndpoint = settings.mtlsEndpoint;
this.switchToMtlsEndpointAllowed = settings.switchToMtlsEndpointAllowed;
Expand Down Expand Up @@ -272,6 +284,7 @@ protected Builder(ClientContext clientContext) {
this.headerProvider = new NoHeaderProvider();
this.internalHeaderProvider = new NoHeaderProvider();
this.clock = NanoClock.getDefaultClock();
this.serviceName = null;
this.endpoint = null;
this.mtlsEndpoint = null;
this.quotaProjectId = null;
Expand All @@ -292,6 +305,7 @@ protected Builder(ClientContext clientContext) {
this.internalHeaderProvider =
FixedHeaderProvider.create(clientContext.getInternalHeaders());
this.clock = clientContext.getClock();
this.serviceName = clientContext.getServiceName();
this.endpoint = clientContext.getEndpoint();
if (this.endpoint != null) {
this.mtlsEndpoint = this.endpoint.replace("googleapis.com", "mtls.googleapis.com");
Expand Down
Expand Up @@ -182,6 +182,12 @@ public ConnectionServiceStub createStub() throws IOException {
"Transport not supported: %s", getTransportChannelProvider().getTransportName()));
}

/** Returns the default service name. */
@Override
public String getServiceName() {
return "apigeeconnect";
}

/** Returns a builder for the default ExecutorProvider for this service. */
public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder() {
return InstantiatingExecutorProvider.newBuilder();
Expand Down
Expand Up @@ -102,6 +102,12 @@ public TetherStub createStub() throws IOException {
"Transport not supported: %s", getTransportChannelProvider().getTransportName()));
}

/** Returns the default service name. */
@Override
public String getServiceName() {
return "apigeeconnect";
}

/** Returns a builder for the default ExecutorProvider for this service. */
public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder() {
return InstantiatingExecutorProvider.newBuilder();
Expand Down
Expand Up @@ -571,6 +571,12 @@ public AssetServiceStub createStub() throws IOException {
"Transport not supported: %s", getTransportChannelProvider().getTransportName()));
}

/** Returns the default service name. */
@Override
public String getServiceName() {
return "cloudasset";
}

/** Returns a builder for the default ExecutorProvider for this service. */
public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder() {
return InstantiatingExecutorProvider.newBuilder();
Expand Down
Expand Up @@ -166,6 +166,12 @@ public BigtableStub createStub() throws IOException {
"Transport not supported: %s", getTransportChannelProvider().getTransportName()));
}

/** Returns the default service name. */
@Override
public String getServiceName() {
return "bigtable";
}

/** Returns a builder for the default ExecutorProvider for this service. */
public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder() {
return InstantiatingExecutorProvider.newBuilder();
Expand Down
Expand Up @@ -289,6 +289,12 @@ public AddressesStub createStub() throws IOException {
"Transport not supported: %s", getTransportChannelProvider().getTransportName()));
}

/** Returns the default service name. */
@Override
public String getServiceName() {
return "compute";
}

/** Returns a builder for the default ExecutorProvider for this service. */
public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder() {
return InstantiatingExecutorProvider.newBuilder();
Expand Down
Expand Up @@ -114,6 +114,12 @@ public RegionOperationsStub createStub() throws IOException {
"Transport not supported: %s", getTransportChannelProvider().getTransportName()));
}

/** Returns the default service name. */
@Override
public String getServiceName() {
return "compute";
}

/** Returns a builder for the default ExecutorProvider for this service. */
public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder() {
return InstantiatingExecutorProvider.newBuilder();
Expand Down
Expand Up @@ -140,6 +140,12 @@ public IamCredentialsStub createStub() throws IOException {
"Transport not supported: %s", getTransportChannelProvider().getTransportName()));
}

/** Returns the default service name. */
@Override
public String getServiceName() {
return "iamcredentials";
}

/** Returns a builder for the default ExecutorProvider for this service. */
public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder() {
return InstantiatingExecutorProvider.newBuilder();
Expand Down
Expand Up @@ -119,6 +119,12 @@ public IAMPolicyStub createStub() throws IOException {
"Transport not supported: %s", getTransportChannelProvider().getTransportName()));
}

/** Returns the default service name. */
@Override
public String getServiceName() {
return "iam-meta-api";
}

/** Returns a builder for the default ExecutorProvider for this service. */
public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder() {
return InstantiatingExecutorProvider.newBuilder();
Expand Down
Expand Up @@ -639,6 +639,12 @@ public KeyManagementServiceStub createStub() throws IOException {
"Transport not supported: %s", getTransportChannelProvider().getTransportName()));
}

/** Returns the default service name. */
@Override
public String getServiceName() {
return "cloudkms";
}

/** Returns a builder for the default ExecutorProvider for this service. */
public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder() {
return InstantiatingExecutorProvider.newBuilder();
Expand Down
Expand Up @@ -306,6 +306,12 @@ public LibraryServiceStub createStub() throws IOException {
"Transport not supported: %s", getTransportChannelProvider().getTransportName()));
}

/** Returns the default service name. */
@Override
public String getServiceName() {
return "library-example";
}

/** Returns a builder for the default ExecutorProvider for this service. */
public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder() {
return InstantiatingExecutorProvider.newBuilder();
Expand Down

0 comments on commit 8822f3b

Please sign in to comment.