diff --git a/gapic-generator-java/src/main/java/com/google/api/generator/engine/ast/TypeNode.java b/gapic-generator-java/src/main/java/com/google/api/generator/engine/ast/TypeNode.java index b217feb057..12236842fc 100644 --- a/gapic-generator-java/src/main/java/com/google/api/generator/engine/ast/TypeNode.java +++ b/gapic-generator-java/src/main/java/com/google/api/generator/engine/ast/TypeNode.java @@ -74,6 +74,17 @@ public enum TypeKind { withReference( VaporReference.builder().setName("Value").setPakkage("com.google.protobuf").build()); + public static final TypeNode UINT32VALUE = + withReference( + VaporReference.builder() + .setName("UInt32Value") + .setPakkage("com.google.protobuf") + .build()); + + public static final TypeNode INT32VALUE = + withReference( + VaporReference.builder().setName("Int32Value").setPakkage("com.google.protobuf").build()); + private static final Map BOXED_TYPE_MAP = createBoxedTypeMap(); public static final TypeNode VOID = builder().setTypeKind(TypeKind.VOID).build(); diff --git a/gapic-generator-java/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceStubSettingsClassComposer.java b/gapic-generator-java/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceStubSettingsClassComposer.java index 6357ee3f3c..45c5d2193e 100644 --- a/gapic-generator-java/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceStubSettingsClassComposer.java +++ b/gapic-generator-java/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceStubSettingsClassComposer.java @@ -149,6 +149,20 @@ public abstract class AbstractServiceStubSettingsClassComposer implements ClassC private final TransportContext transportContext; + // Maps of BigQuery methods to pagination types. + private static final ImmutableMap BIGQUERY_PAGINATE_MAX_RESULT_TYPES = + ImmutableMap.of( + "com.google.cloud.bigquery.v2.ListDatasets", + TypeNode.UINT32VALUE, + "com.google.cloud.bigquery.v2.ListJobs", + TypeNode.INT32VALUE, + "com.google.cloud.bigquery.v2.ListModels", + TypeNode.UINT32VALUE, + "com.google.cloud.bigquery.v2.ListRoutines", + TypeNode.UINT32VALUE, + "com.google.cloud.bigquery.v2.ListTables", + TypeNode.UINT32VALUE); + protected static final VariableExpr DEFAULT_SERVICE_SCOPES_VAR_EXPR = createDefaultServiceScopesVarExpr(); @@ -727,9 +741,12 @@ private static Expr createPagedListDescriptorAssignExpr( .build()); // Create injectPageSize method. + String methodFullName = + String.format("%s.%s", method.inputType().reference().pakkage(), method.name()); VariableExpr pageSizeVarExpr = VariableExpr.withVariable( Variable.builder().setType(TypeNode.INT).setName("pageSize").build()); + // Re-declare for clarity and easier readability. returnType = method.inputType(); returnExpr = @@ -738,6 +755,20 @@ private static Expr createPagedListDescriptorAssignExpr( .setMethodName("set" + JavaStyle.toUpperCamelCase(method.pageSizeFieldName())) .setArguments(pageSizeVarExpr) .build(); + if (BIGQUERY_PAGINATE_MAX_RESULT_TYPES.containsKey(methodFullName)) { + returnExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(newBuilderExpr) + .setMethodName("set" + JavaStyle.toUpperCamelCase(method.pageSizeFieldName())) + .setArguments( + MethodInvocationExpr.builder() + .setStaticReferenceType( + BIGQUERY_PAGINATE_MAX_RESULT_TYPES.get(methodFullName)) + .setMethodName("of") + .setArguments(pageSizeVarExpr) + .build()) + .build(); + } returnExpr = MethodInvocationExpr.builder() .setExprReferenceExpr(returnExpr) @@ -758,17 +789,32 @@ private static Expr createPagedListDescriptorAssignExpr( // TODO(miraleung): Test the edge cases where these proto fields aren't present. // Create extractPageSize method. returnType = TypeNode.INT_OBJECT; + returnExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(payloadVarExpr) + .setMethodName("get" + JavaStyle.toUpperCamelCase(method.pageSizeFieldName())) + .setReturnType(returnType) + .build(); + if (BIGQUERY_PAGINATE_MAX_RESULT_TYPES.containsKey(methodFullName)) { + // Return type is UINT32VALUE or INT32VALUE so use getValue to unwrap. + returnExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(payloadVarExpr) + .setMethodName("get" + JavaStyle.toUpperCamelCase(method.pageSizeFieldName())) + .build(); + returnExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(returnExpr) + .setMethodName("getValue") + .setReturnType(returnType) + .build(); + } anonClassMethods.add( methodStarterBuilder .setReturnType(returnType) .setName("extractPageSize") .setArguments(payloadVarExpr.toBuilder().setIsDecl(true).build()) - .setReturnExpr( - MethodInvocationExpr.builder() - .setExprReferenceExpr(payloadVarExpr) - .setMethodName("get" + JavaStyle.toUpperCamelCase(method.pageSizeFieldName())) - .setReturnType(returnType) - .build()) + .setReturnExpr(returnExpr) .build()); // Create extractNextToken method. diff --git a/gapic-generator-java/src/main/java/com/google/api/generator/gapic/protoparser/Parser.java b/gapic-generator-java/src/main/java/com/google/api/generator/gapic/protoparser/Parser.java index 975ccf58fa..0ff6a71039 100644 --- a/gapic-generator-java/src/main/java/com/google/api/generator/gapic/protoparser/Parser.java +++ b/gapic-generator-java/src/main/java/com/google/api/generator/gapic/protoparser/Parser.java @@ -121,6 +121,16 @@ enum SelectiveGapicType { private static final Set MIXIN_JAVA_PACKAGE_ALLOWLIST = ImmutableSet.of("com.google.iam.v1", "com.google.longrunning", "com.google.cloud.location"); + // List of BigQuery methods that can use max_result field as an alternative to page_size for + // pagination. + private static final ImmutableSet BIGQUERY_LEGACY_PAGINATION_ALLOWLIST = + ImmutableSet.of( + "google.cloud.bigquery.v2.JobService.ListJobs", + "google.cloud.bigquery.v2.RoutineService.ListRoutines", + "google.cloud.bigquery.v2.DatasetService.ListDatasets", + "google.cloud.bigquery.v2.ModelService.ListModels", + "google.cloud.bigquery.v2.TableService.ListTables"); + // Allow other parsers to access this. protected static final SourceCodeInfoParser SOURCE_CODE_INFO_PARSER = new SourceCodeInfoParser(); @@ -1029,7 +1039,8 @@ static String parsePageSizeFieldName( // page_size gets priority over max_results if both are present List fieldNames = new ArrayList<>(); fieldNames.add("page_size"); - if (transport == Transport.REST) { + if ((transport == Transport.REST) + || (BIGQUERY_LEGACY_PAGINATION_ALLOWLIST.contains(methodDescriptor.getFullName()))) { fieldNames.add("max_results"); } for (String fieldName : fieldNames) { diff --git a/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/ClientLibraryReflectConfigComposerTest.java b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/ClientLibraryReflectConfigComposerTest.java index 715c7d5f7f..31d3f7a578 100644 --- a/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/ClientLibraryReflectConfigComposerTest.java +++ b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/ClientLibraryReflectConfigComposerTest.java @@ -61,6 +61,8 @@ void composeReflectConfigs_showcase() { "com.google.showcase.v1beta1.Foobar$Builder", "com.google.showcase.v1beta1.Object", "com.google.showcase.v1beta1.Object$Builder", + "com.google.showcase.v1beta1.PagedExpandLegacyRequest", + "com.google.showcase.v1beta1.PagedExpandLegacyRequest$Builder", "com.google.showcase.v1beta1.PagedExpandRequest", "com.google.showcase.v1beta1.PagedExpandRequest$Builder", "com.google.showcase.v1beta1.PagedExpandResponse", diff --git a/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceStubClassComposerTest.java b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceStubClassComposerTest.java index 5c910cd618..bde0a9c2d5 100644 --- a/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceStubClassComposerTest.java +++ b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceStubClassComposerTest.java @@ -101,4 +101,15 @@ void generateGrpcServiceStubClass_callableNameType() { Assert.assertGoldenClass(this.getClass(), clazz, "GrpcCallableNameTypeStub.golden"); Assert.assertEmptySamples(clazz.samples()); } + + @Test + void generateGrpcServiceStubClass_bigQuery() { + GapicContext context = GrpcTestProtoLoader.instance().parseBigqueryService(); + + Service bigqueryJobService = context.services().get(0); + GapicClass clazz = + GrpcServiceStubClassComposer.instance().generate(context, bigqueryJobService); + Assert.assertGoldenClass(this.getClass(), clazz, "GrpcBigQueryJobServiceStub.golden"); + Assert.assertEmptySamples(clazz.samples()); + } } diff --git a/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/ServiceStubSettingsClassComposerTest.java b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/ServiceStubSettingsClassComposerTest.java index fb6c34d451..3287309ee4 100644 --- a/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/ServiceStubSettingsClassComposerTest.java +++ b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/ServiceStubSettingsClassComposerTest.java @@ -62,7 +62,13 @@ static Stream data() { GrpcTestProtoLoader.instance().parseSelectiveGenerationTesting(), "localhost:7469", "v1beta1", - 1)); + 1), + Arguments.of( + "JobServiceStubSettings", + GrpcTestProtoLoader.instance().parseBigqueryService(), + "bigquery", + "v2", + 0)); } @ParameterizedTest diff --git a/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoClient.golden b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoClient.golden index 431700191c..612111aea0 100644 --- a/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoClient.golden +++ b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoClient.golden @@ -206,6 +206,20 @@ import javax.annotation.Generated; * * * + * + *

PagedExpandLegacy + *

+ * + *

Request object method variants only take one parameter, a request object, which must be constructed before the call.

+ *
    + *
  • pagedExpandLegacy(PagedExpandLegacyRequest request) + *

+ *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • pagedExpandLegacyCallable() + *

+ * + * * * *

See the individual methods for example code. @@ -1124,6 +1138,63 @@ public class EchoClient implements BackgroundResource { return stub.collideNameCallable(); } + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Sample code: + * + *

{@code
+   * // This snippet has been automatically generated and should be regarded as a code template only.
+   * // It will require modifications to work:
+   * // - It may require correct/in-range values for request initialization.
+   * // - It may require specifying regional endpoints when creating the service client as shown in
+   * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+   * try (EchoClient echoClient = EchoClient.create()) {
+   *   PagedExpandLegacyRequest request =
+   *       PagedExpandLegacyRequest.newBuilder()
+   *           .setContent("content951530617")
+   *           .setMaxResults(1128457243)
+   *           .setPageToken("pageToken873572522")
+   *           .build();
+   *   PagedExpandResponse response = echoClient.pagedExpandLegacy(request);
+   * }
+   * }
+ * + * @param request The request object containing all of the parameters for the API call. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final PagedExpandResponse pagedExpandLegacy(PagedExpandLegacyRequest request) { + return pagedExpandLegacyCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Sample code: + * + *
{@code
+   * // This snippet has been automatically generated and should be regarded as a code template only.
+   * // It will require modifications to work:
+   * // - It may require correct/in-range values for request initialization.
+   * // - It may require specifying regional endpoints when creating the service client as shown in
+   * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+   * try (EchoClient echoClient = EchoClient.create()) {
+   *   PagedExpandLegacyRequest request =
+   *       PagedExpandLegacyRequest.newBuilder()
+   *           .setContent("content951530617")
+   *           .setMaxResults(1128457243)
+   *           .setPageToken("pageToken873572522")
+   *           .build();
+   *   ApiFuture future =
+   *       echoClient.pagedExpandLegacyCallable().futureCall(request);
+   *   // Do something.
+   *   PagedExpandResponse response = future.get();
+   * }
+   * }
+ */ + public final UnaryCallable + pagedExpandLegacyCallable() { + return stub.pagedExpandLegacyCallable(); + } + @Override public final void close() { stub.close(); diff --git a/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoClientTest.golden b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoClientTest.golden index 1372cdd94e..515649a093 100644 --- a/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoClientTest.golden +++ b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoClientTest.golden @@ -26,6 +26,7 @@ import com.google.protobuf.Timestamp; import com.google.rpc.Status; import io.grpc.StatusRuntimeException; import java.io.IOException; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.UUID; @@ -890,4 +891,55 @@ public class EchoClientTest { // Expected exception. } } + + @Test + public void pagedExpandLegacyTest() throws Exception { + PagedExpandResponse expectedResponse = + PagedExpandResponse.newBuilder() + .addAllResponses(new ArrayList()) + .setNextPageToken("nextPageToken-1386094857") + .build(); + mockEcho.addResponse(expectedResponse); + + PagedExpandLegacyRequest request = + PagedExpandLegacyRequest.newBuilder() + .setContent("content951530617") + .setMaxResults(1128457243) + .setPageToken("pageToken873572522") + .build(); + + PagedExpandResponse actualResponse = client.pagedExpandLegacy(request); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockEcho.getRequests(); + Assert.assertEquals(1, actualRequests.size()); + PagedExpandLegacyRequest actualRequest = ((PagedExpandLegacyRequest) actualRequests.get(0)); + + Assert.assertEquals(request.getContent(), actualRequest.getContent()); + Assert.assertEquals(request.getMaxResults(), actualRequest.getMaxResults()); + Assert.assertEquals(request.getPageToken(), actualRequest.getPageToken()); + Assert.assertTrue( + channelProvider.isHeaderSent( + ApiClientHeaderProvider.getDefaultApiClientHeaderKey(), + GaxGrpcProperties.getDefaultApiClientHeaderPattern())); + } + + @Test + public void pagedExpandLegacyExceptionTest() throws Exception { + StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); + mockEcho.addException(exception); + + try { + PagedExpandLegacyRequest request = + PagedExpandLegacyRequest.newBuilder() + .setContent("content951530617") + .setMaxResults(1128457243) + .setPageToken("pageToken873572522") + .build(); + client.pagedExpandLegacy(request); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } } diff --git a/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoSettings.golden b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoSettings.golden index e3cfa3f0f2..deb3a387bf 100644 --- a/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoSettings.golden +++ b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoSettings.golden @@ -159,6 +159,12 @@ public class EchoSettings extends ClientSettings { return ((EchoStubSettings) getStubSettings()).collideNameSettings(); } + /** Returns the object with the settings used for calls to pagedExpandLegacy. */ + public UnaryCallSettings + pagedExpandLegacySettings() { + return ((EchoStubSettings) getStubSettings()).pagedExpandLegacySettings(); + } + public static final EchoSettings create(EchoStubSettings stub) throws IOException { return new EchoSettings.Builder(stub.toBuilder()).build(); } @@ -314,6 +320,12 @@ public class EchoSettings extends ClientSettings { return getStubSettingsBuilder().collideNameSettings(); } + /** Returns the builder for the settings used for calls to pagedExpandLegacy. */ + public UnaryCallSettings.Builder + pagedExpandLegacySettings() { + return getStubSettingsBuilder().pagedExpandLegacySettings(); + } + @Override public EchoSettings build() throws IOException { return new EchoSettings(this); diff --git a/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoStub.golden b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoStub.golden index 9270f22851..c43465da68 100644 --- a/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoStub.golden +++ b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoStub.golden @@ -18,6 +18,7 @@ import com.google.showcase.v1beta1.EchoRequest; import com.google.showcase.v1beta1.EchoResponse; import com.google.showcase.v1beta1.ExpandRequest; import com.google.showcase.v1beta1.Object; +import com.google.showcase.v1beta1.PagedExpandLegacyRequest; import com.google.showcase.v1beta1.PagedExpandRequest; import com.google.showcase.v1beta1.PagedExpandResponse; import com.google.showcase.v1beta1.WaitMetadata; @@ -92,6 +93,10 @@ public abstract class EchoStub implements BackgroundResource { throw new UnsupportedOperationException("Not implemented: collideNameCallable()"); } + public UnaryCallable pagedExpandLegacyCallable() { + throw new UnsupportedOperationException("Not implemented: pagedExpandLegacyCallable()"); + } + @Override public abstract void close(); } diff --git a/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoStubSettings.golden b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoStubSettings.golden index e43bb64604..77d8fbf45a 100644 --- a/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoStubSettings.golden +++ b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoStubSettings.golden @@ -43,6 +43,7 @@ import com.google.showcase.v1beta1.EchoRequest; import com.google.showcase.v1beta1.EchoResponse; import com.google.showcase.v1beta1.ExpandRequest; import com.google.showcase.v1beta1.Object; +import com.google.showcase.v1beta1.PagedExpandLegacyRequest; import com.google.showcase.v1beta1.PagedExpandRequest; import com.google.showcase.v1beta1.PagedExpandResponse; import com.google.showcase.v1beta1.WaitMetadata; @@ -149,6 +150,8 @@ public class EchoStubSettings extends StubSettings { waitOperationSettings; private final UnaryCallSettings blockSettings; private final UnaryCallSettings collideNameSettings; + private final UnaryCallSettings + pagedExpandLegacySettings; private static final PagedListDescriptor PAGED_EXPAND_PAGE_STR_DESC = @@ -309,6 +312,12 @@ public class EchoStubSettings extends StubSettings { return collideNameSettings; } + /** Returns the object with the settings used for calls to pagedExpandLegacy. */ + public UnaryCallSettings + pagedExpandLegacySettings() { + return pagedExpandLegacySettings; + } + public EchoStub createStub() throws IOException { if (getTransportChannelProvider() .getTransportName() @@ -394,6 +403,7 @@ public class EchoStubSettings extends StubSettings { waitOperationSettings = settingsBuilder.waitOperationSettings().build(); blockSettings = settingsBuilder.blockSettings().build(); collideNameSettings = settingsBuilder.collideNameSettings().build(); + pagedExpandLegacySettings = settingsBuilder.pagedExpandLegacySettings().build(); } /** Builder for EchoStubSettings. */ @@ -415,6 +425,8 @@ public class EchoStubSettings extends StubSettings { waitOperationSettings; private final UnaryCallSettings.Builder blockSettings; private final UnaryCallSettings.Builder collideNameSettings; + private final UnaryCallSettings.Builder + pagedExpandLegacySettings; private static final ImmutableMap> RETRYABLE_CODE_DEFINITIONS; @@ -476,6 +488,7 @@ public class EchoStubSettings extends StubSettings { waitOperationSettings = OperationCallSettings.newBuilder(); blockSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); collideNameSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); + pagedExpandLegacySettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); unaryMethodSettingsBuilders = ImmutableList.>of( @@ -484,7 +497,8 @@ public class EchoStubSettings extends StubSettings { simplePagedExpandSettings, waitSettings, blockSettings, - collideNameSettings); + collideNameSettings, + pagedExpandLegacySettings); initDefaults(this); } @@ -502,6 +516,7 @@ public class EchoStubSettings extends StubSettings { waitOperationSettings = settings.waitOperationSettings.toBuilder(); blockSettings = settings.blockSettings.toBuilder(); collideNameSettings = settings.collideNameSettings.toBuilder(); + pagedExpandLegacySettings = settings.pagedExpandLegacySettings.toBuilder(); unaryMethodSettingsBuilders = ImmutableList.>of( @@ -510,7 +525,8 @@ public class EchoStubSettings extends StubSettings { simplePagedExpandSettings, waitSettings, blockSettings, - collideNameSettings); + collideNameSettings, + pagedExpandLegacySettings); } private static Builder createDefault() { @@ -561,6 +577,11 @@ public class EchoStubSettings extends StubSettings { .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_0_codes")) .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_0_params")); + builder + .pagedExpandLegacySettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_0_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_0_params")); + builder .waitOperationSettings() .setInitialCallSettings( @@ -662,6 +683,12 @@ public class EchoStubSettings extends StubSettings { return collideNameSettings; } + /** Returns the builder for the settings used for calls to pagedExpandLegacy. */ + public UnaryCallSettings.Builder + pagedExpandLegacySettings() { + return pagedExpandLegacySettings; + } + @Override public EchoStubSettings build() throws IOException { return new EchoStubSettings(this); diff --git a/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/GrpcBigQueryJobServiceStub.golden b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/GrpcBigQueryJobServiceStub.golden new file mode 100644 index 0000000000..c1c51ff44b --- /dev/null +++ b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/GrpcBigQueryJobServiceStub.golden @@ -0,0 +1,187 @@ +package com.google.cloud.bigquery.v2.stub; + +import static com.google.cloud.bigquery.v2.JobServiceClient.ListJobsPagedResponse; + +import com.google.api.gax.core.BackgroundResource; +import com.google.api.gax.core.BackgroundResourceAggregation; +import com.google.api.gax.grpc.GrpcCallSettings; +import com.google.api.gax.grpc.GrpcStubCallableFactory; +import com.google.api.gax.rpc.ClientContext; +import com.google.api.gax.rpc.RequestParamsBuilder; +import com.google.api.gax.rpc.UnaryCallable; +import com.google.cloud.bigquery.v2.JobProto; +import com.google.longrunning.stub.GrpcOperationsStub; +import com.google.protobuf.Empty; +import io.grpc.MethodDescriptor; +import io.grpc.protobuf.ProtoUtils; +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * gRPC stub implementation for the JobService service API. + * + *

This class is for advanced usage and reflects the underlying API directly. + */ +@Generated("by gapic-generator-java") +public class GrpcJobServiceStub extends JobServiceStub { + private static final MethodDescriptor + deleteJobMethodDescriptor = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.UNARY) + .setFullMethodName("google.cloud.bigquery.v2.JobService/DeleteJob") + .setRequestMarshaller( + ProtoUtils.marshaller(JobProto.DeleteJobRequest.getDefaultInstance())) + .setResponseMarshaller(ProtoUtils.marshaller(Empty.getDefaultInstance())) + .build(); + + private static final MethodDescriptor + listJobsMethodDescriptor = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.UNARY) + .setFullMethodName("google.cloud.bigquery.v2.JobService/ListJobs") + .setRequestMarshaller( + ProtoUtils.marshaller(JobProto.ListJobsRequest.getDefaultInstance())) + .setResponseMarshaller(ProtoUtils.marshaller(JobProto.JobList.getDefaultInstance())) + .build(); + + private final UnaryCallable deleteJobCallable; + private final UnaryCallable listJobsCallable; + private final UnaryCallable + listJobsPagedCallable; + + private final BackgroundResource backgroundResources; + private final GrpcOperationsStub operationsStub; + private final GrpcStubCallableFactory callableFactory; + + public static final GrpcJobServiceStub create(JobServiceStubSettings settings) + throws IOException { + return new GrpcJobServiceStub(settings, ClientContext.create(settings)); + } + + public static final GrpcJobServiceStub create(ClientContext clientContext) throws IOException { + return new GrpcJobServiceStub(JobServiceStubSettings.newBuilder().build(), clientContext); + } + + public static final GrpcJobServiceStub create( + ClientContext clientContext, GrpcStubCallableFactory callableFactory) throws IOException { + return new GrpcJobServiceStub( + JobServiceStubSettings.newBuilder().build(), clientContext, callableFactory); + } + + /** + * Constructs an instance of GrpcJobServiceStub, using the given settings. This is protected so + * that it is easy to make a subclass, but otherwise, the static factory methods should be + * preferred. + */ + protected GrpcJobServiceStub(JobServiceStubSettings settings, ClientContext clientContext) + throws IOException { + this(settings, clientContext, new GrpcJobServiceCallableFactory()); + } + + /** + * Constructs an instance of GrpcJobServiceStub, using the given settings. This is protected so + * that it is easy to make a subclass, but otherwise, the static factory methods should be + * preferred. + */ + protected GrpcJobServiceStub( + JobServiceStubSettings settings, + ClientContext clientContext, + GrpcStubCallableFactory callableFactory) + throws IOException { + this.callableFactory = callableFactory; + this.operationsStub = GrpcOperationsStub.create(clientContext, callableFactory); + + GrpcCallSettings deleteJobTransportSettings = + GrpcCallSettings.newBuilder() + .setMethodDescriptor(deleteJobMethodDescriptor) + .setParamsExtractor( + request -> { + RequestParamsBuilder builder = RequestParamsBuilder.create(); + builder.add("job_id", String.valueOf(request.getJobId())); + builder.add("project_id", String.valueOf(request.getProjectId())); + return builder.build(); + }) + .build(); + GrpcCallSettings listJobsTransportSettings = + GrpcCallSettings.newBuilder() + .setMethodDescriptor(listJobsMethodDescriptor) + .setParamsExtractor( + request -> { + RequestParamsBuilder builder = RequestParamsBuilder.create(); + builder.add("project_id", String.valueOf(request.getProjectId())); + return builder.build(); + }) + .build(); + + this.deleteJobCallable = + callableFactory.createUnaryCallable( + deleteJobTransportSettings, settings.deleteJobSettings(), clientContext); + this.listJobsCallable = + callableFactory.createUnaryCallable( + listJobsTransportSettings, settings.listJobsSettings(), clientContext); + this.listJobsPagedCallable = + callableFactory.createPagedCallable( + listJobsTransportSettings, settings.listJobsSettings(), clientContext); + + this.backgroundResources = + new BackgroundResourceAggregation(clientContext.getBackgroundResources()); + } + + public GrpcOperationsStub getOperationsStub() { + return operationsStub; + } + + @Override + public UnaryCallable deleteJobCallable() { + return deleteJobCallable; + } + + @Override + public UnaryCallable listJobsCallable() { + return listJobsCallable; + } + + @Override + public UnaryCallable listJobsPagedCallable() { + return listJobsPagedCallable; + } + + @Override + public final void close() { + try { + backgroundResources.close(); + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new IllegalStateException("Failed to close resource", e); + } + } + + @Override + public void shutdown() { + backgroundResources.shutdown(); + } + + @Override + public boolean isShutdown() { + return backgroundResources.isShutdown(); + } + + @Override + public boolean isTerminated() { + return backgroundResources.isTerminated(); + } + + @Override + public void shutdownNow() { + backgroundResources.shutdownNow(); + } + + @Override + public boolean awaitTermination(long duration, TimeUnit unit) throws InterruptedException { + return backgroundResources.awaitTermination(duration, unit); + } +} diff --git a/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/GrpcEchoStub.golden b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/GrpcEchoStub.golden index 940ab7d4c4..7972dc929b 100644 --- a/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/GrpcEchoStub.golden +++ b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/GrpcEchoStub.golden @@ -22,6 +22,7 @@ import com.google.showcase.v1beta1.EchoRequest; import com.google.showcase.v1beta1.EchoResponse; import com.google.showcase.v1beta1.ExpandRequest; import com.google.showcase.v1beta1.Object; +import com.google.showcase.v1beta1.PagedExpandLegacyRequest; import com.google.showcase.v1beta1.PagedExpandRequest; import com.google.showcase.v1beta1.PagedExpandResponse; import com.google.showcase.v1beta1.WaitMetadata; @@ -126,6 +127,17 @@ public class GrpcEchoStub extends EchoStub { .setResponseMarshaller(ProtoUtils.marshaller(Object.getDefaultInstance())) .build(); + private static final MethodDescriptor + pagedExpandLegacyMethodDescriptor = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.UNARY) + .setFullMethodName("google.showcase.v1beta1.Echo/PagedExpandLegacy") + .setRequestMarshaller( + ProtoUtils.marshaller(PagedExpandLegacyRequest.getDefaultInstance())) + .setResponseMarshaller( + ProtoUtils.marshaller(PagedExpandResponse.getDefaultInstance())) + .build(); + private final UnaryCallable echoCallable; private final ServerStreamingCallable expandCallable; private final ClientStreamingCallable collectCallable; @@ -141,6 +153,8 @@ public class GrpcEchoStub extends EchoStub { private final OperationCallable waitOperationCallable; private final UnaryCallable blockCallable; private final UnaryCallable collideNameCallable; + private final UnaryCallable + pagedExpandLegacyCallable; private final BackgroundResource backgroundResources; private final GrpcOperationsStub operationsStub; @@ -220,6 +234,11 @@ public class GrpcEchoStub extends EchoStub { GrpcCallSettings.newBuilder() .setMethodDescriptor(collideNameMethodDescriptor) .build(); + GrpcCallSettings + pagedExpandLegacyTransportSettings = + GrpcCallSettings.newBuilder() + .setMethodDescriptor(pagedExpandLegacyMethodDescriptor) + .build(); this.echoCallable = callableFactory.createUnaryCallable( @@ -264,6 +283,11 @@ public class GrpcEchoStub extends EchoStub { this.collideNameCallable = callableFactory.createUnaryCallable( collideNameTransportSettings, settings.collideNameSettings(), clientContext); + this.pagedExpandLegacyCallable = + callableFactory.createUnaryCallable( + pagedExpandLegacyTransportSettings, + settings.pagedExpandLegacySettings(), + clientContext); this.backgroundResources = new BackgroundResourceAggregation(clientContext.getBackgroundResources()); @@ -339,6 +363,11 @@ public class GrpcEchoStub extends EchoStub { return collideNameCallable; } + @Override + public UnaryCallable pagedExpandLegacyCallable() { + return pagedExpandLegacyCallable; + } + @Override public final void close() { try { diff --git a/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/JobServiceStubSettings.golden b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/JobServiceStubSettings.golden new file mode 100644 index 0000000000..d4bf730476 --- /dev/null +++ b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/JobServiceStubSettings.golden @@ -0,0 +1,376 @@ +package com.google.cloud.bigquery.v2.stub; + +import static com.google.cloud.bigquery.v2.JobServiceClient.ListJobsPagedResponse; + +import com.google.api.core.ApiFunction; +import com.google.api.core.ApiFuture; +import com.google.api.core.ObsoleteApi; +import com.google.api.gax.core.GaxProperties; +import com.google.api.gax.core.GoogleCredentialsProvider; +import com.google.api.gax.core.InstantiatingExecutorProvider; +import com.google.api.gax.grpc.GaxGrpcProperties; +import com.google.api.gax.grpc.GrpcTransportChannel; +import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider; +import com.google.api.gax.retrying.RetrySettings; +import com.google.api.gax.rpc.ApiCallContext; +import com.google.api.gax.rpc.ApiClientHeaderProvider; +import com.google.api.gax.rpc.ClientContext; +import com.google.api.gax.rpc.PageContext; +import com.google.api.gax.rpc.PagedCallSettings; +import com.google.api.gax.rpc.PagedListDescriptor; +import com.google.api.gax.rpc.PagedListResponseFactory; +import com.google.api.gax.rpc.StatusCode; +import com.google.api.gax.rpc.StubSettings; +import com.google.api.gax.rpc.TransportChannelProvider; +import com.google.api.gax.rpc.UnaryCallSettings; +import com.google.api.gax.rpc.UnaryCallable; +import com.google.cloud.bigquery.v2.JobProto; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; +import com.google.protobuf.Empty; +import com.google.protobuf.Int32Value; +import java.io.IOException; +import java.time.Duration; +import java.util.List; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * Settings class to configure an instance of {@link JobServiceStub}. + * + *

The default instance has everything set to sensible defaults: + * + *

    + *
  • The default service address (bigquery.googleapis.com) and default port (443) are used. + *
  • Credentials are acquired automatically through Application Default Credentials. + *
  • Retries are configured for idempotent methods but not for non-idempotent methods. + *
+ * + *

The builder of this class is recursive, so contained classes are themselves builders. When + * build() is called, the tree of builders is called to create the complete settings object. + * + *

For example, to set the + * [RetrySettings](https://cloud.google.com/java/docs/reference/gax/latest/com.google.api.gax.retrying.RetrySettings) + * of deleteJob: + * + *

{@code
+ * // This snippet has been automatically generated and should be regarded as a code template only.
+ * // It will require modifications to work:
+ * // - It may require correct/in-range values for request initialization.
+ * // - It may require specifying regional endpoints when creating the service client as shown in
+ * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+ * JobServiceStubSettings.Builder jobServiceSettingsBuilder = JobServiceStubSettings.newBuilder();
+ * jobServiceSettingsBuilder
+ *     .deleteJobSettings()
+ *     .setRetrySettings(
+ *         jobServiceSettingsBuilder
+ *             .deleteJobSettings()
+ *             .getRetrySettings()
+ *             .toBuilder()
+ *             .setInitialRetryDelayDuration(Duration.ofSeconds(1))
+ *             .setInitialRpcTimeoutDuration(Duration.ofSeconds(5))
+ *             .setMaxAttempts(5)
+ *             .setMaxRetryDelayDuration(Duration.ofSeconds(30))
+ *             .setMaxRpcTimeoutDuration(Duration.ofSeconds(60))
+ *             .setRetryDelayMultiplier(1.3)
+ *             .setRpcTimeoutMultiplier(1.5)
+ *             .setTotalTimeoutDuration(Duration.ofSeconds(300))
+ *             .build());
+ * JobServiceStubSettings jobServiceSettings = jobServiceSettingsBuilder.build();
+ * }
+ * + * Please refer to the [Client Side Retry + * Guide](https://github.com/googleapis/google-cloud-java/blob/main/docs/client_retries.md) for + * additional support in setting retries. + */ +@Generated("by gapic-generator-java") +public class JobServiceStubSettings extends StubSettings { + /** The default scopes of the service. */ + private static final ImmutableList DEFAULT_SERVICE_SCOPES = + ImmutableList.builder() + .add("https://www.googleapis.com/auth/bigquery") + .add("https://www.googleapis.com/auth/cloud-platform") + .add("https://www.googleapis.com/auth/cloud-platform.read-only") + .add("https://www.googleapis.com/auth/devstorage.full_control") + .add("https://www.googleapis.com/auth/devstorage.read_only") + .add("https://www.googleapis.com/auth/devstorage.read_write") + .build(); + + private final UnaryCallSettings deleteJobSettings; + private final PagedCallSettings + listJobsSettings; + + private static final PagedListDescriptor< + JobProto.ListJobsRequest, JobProto.JobList, JobProto.ListFormatJob> + LIST_JOBS_PAGE_STR_DESC = + new PagedListDescriptor< + JobProto.ListJobsRequest, JobProto.JobList, JobProto.ListFormatJob>() { + @Override + public String emptyToken() { + return ""; + } + + @Override + public JobProto.ListJobsRequest injectToken( + JobProto.ListJobsRequest payload, String token) { + return JobProto.ListJobsRequest.newBuilder(payload).setPageToken(token).build(); + } + + @Override + public JobProto.ListJobsRequest injectPageSize( + JobProto.ListJobsRequest payload, int pageSize) { + return JobProto.ListJobsRequest.newBuilder(payload) + .setMaxResults(Int32Value.of(pageSize)) + .build(); + } + + @Override + public Integer extractPageSize(JobProto.ListJobsRequest payload) { + return payload.getMaxResults().getValue(); + } + + @Override + public String extractNextToken(JobProto.JobList payload) { + return payload.getNextPageToken(); + } + + @Override + public Iterable extractResources(JobProto.JobList payload) { + return payload.getJobsList(); + } + }; + + private static final PagedListResponseFactory< + JobProto.ListJobsRequest, JobProto.JobList, ListJobsPagedResponse> + LIST_JOBS_PAGE_STR_FACT = + new PagedListResponseFactory< + JobProto.ListJobsRequest, JobProto.JobList, ListJobsPagedResponse>() { + @Override + public ApiFuture getFuturePagedResponse( + UnaryCallable callable, + JobProto.ListJobsRequest request, + ApiCallContext context, + ApiFuture futureResponse) { + PageContext + pageContext = + PageContext.create(callable, LIST_JOBS_PAGE_STR_DESC, request, context); + return ListJobsPagedResponse.createAsync(pageContext, futureResponse); + } + }; + + /** Returns the object with the settings used for calls to deleteJob. */ + public UnaryCallSettings deleteJobSettings() { + return deleteJobSettings; + } + + /** Returns the object with the settings used for calls to listJobs. */ + public PagedCallSettings + listJobsSettings() { + return listJobsSettings; + } + + public JobServiceStub createStub() throws IOException { + if (getTransportChannelProvider() + .getTransportName() + .equals(GrpcTransportChannel.getGrpcTransportName())) { + return GrpcJobServiceStub.create(this); + } + throw new UnsupportedOperationException( + String.format( + "Transport not supported: %s", getTransportChannelProvider().getTransportName())); + } + + /** Returns the default service name. */ + @Override + public String getServiceName() { + return "bigquery"; + } + + /** Returns a builder for the default ExecutorProvider for this service. */ + public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder() { + return InstantiatingExecutorProvider.newBuilder(); + } + + /** Returns the default service endpoint. */ + @ObsoleteApi("Use getEndpoint() instead") + public static String getDefaultEndpoint() { + return "bigquery.googleapis.com:443"; + } + + /** Returns the default mTLS service endpoint. */ + public static String getDefaultMtlsEndpoint() { + return "bigquery.mtls.googleapis.com:443"; + } + + /** Returns the default service scopes. */ + public static List getDefaultServiceScopes() { + return DEFAULT_SERVICE_SCOPES; + } + + /** Returns a builder for the default credentials for this service. */ + public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { + return GoogleCredentialsProvider.newBuilder() + .setScopesToApply(DEFAULT_SERVICE_SCOPES) + .setUseJwtAccessWithScope(true); + } + + /** Returns a builder for the default ChannelProvider for this service. */ + public static InstantiatingGrpcChannelProvider.Builder defaultGrpcTransportProviderBuilder() { + return InstantiatingGrpcChannelProvider.newBuilder() + .setMaxInboundMessageSize(Integer.MAX_VALUE); + } + + public static TransportChannelProvider defaultTransportChannelProvider() { + return defaultGrpcTransportProviderBuilder().build(); + } + + public static ApiClientHeaderProvider.Builder defaultApiClientHeaderProviderBuilder() { + return ApiClientHeaderProvider.newBuilder() + .setGeneratedLibToken( + "gapic", GaxProperties.getLibraryVersion(JobServiceStubSettings.class)) + .setTransportToken( + GaxGrpcProperties.getGrpcTokenName(), GaxGrpcProperties.getGrpcVersion()); + } + + /** Returns a new builder for this class. */ + public static Builder newBuilder() { + return Builder.createDefault(); + } + + /** Returns a new builder for this class. */ + public static Builder newBuilder(ClientContext clientContext) { + return new Builder(clientContext); + } + + /** Returns a builder containing all the values of this settings class. */ + public Builder toBuilder() { + return new Builder(this); + } + + protected JobServiceStubSettings(Builder settingsBuilder) throws IOException { + super(settingsBuilder); + + deleteJobSettings = settingsBuilder.deleteJobSettings().build(); + listJobsSettings = settingsBuilder.listJobsSettings().build(); + } + + /** Builder for JobServiceStubSettings. */ + public static class Builder extends StubSettings.Builder { + private final ImmutableList> unaryMethodSettingsBuilders; + private final UnaryCallSettings.Builder deleteJobSettings; + private final PagedCallSettings.Builder< + JobProto.ListJobsRequest, JobProto.JobList, ListJobsPagedResponse> + listJobsSettings; + private static final ImmutableMap> + RETRYABLE_CODE_DEFINITIONS; + + static { + ImmutableMap.Builder> definitions = + ImmutableMap.builder(); + definitions.put( + "no_retry_0_codes", ImmutableSet.copyOf(Lists.newArrayList())); + RETRYABLE_CODE_DEFINITIONS = definitions.build(); + } + + private static final ImmutableMap RETRY_PARAM_DEFINITIONS; + + static { + ImmutableMap.Builder definitions = ImmutableMap.builder(); + RetrySettings settings = null; + settings = + RetrySettings.newBuilder() + .setInitialRpcTimeoutDuration(Duration.ofMillis(5000L)) + .setRpcTimeoutMultiplier(1.0) + .setMaxRpcTimeoutDuration(Duration.ofMillis(5000L)) + .setTotalTimeoutDuration(Duration.ofMillis(5000L)) + .build(); + definitions.put("no_retry_0_params", settings); + RETRY_PARAM_DEFINITIONS = definitions.build(); + } + + protected Builder() { + this(((ClientContext) null)); + } + + protected Builder(ClientContext clientContext) { + super(clientContext); + + deleteJobSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); + listJobsSettings = PagedCallSettings.newBuilder(LIST_JOBS_PAGE_STR_FACT); + + unaryMethodSettingsBuilders = + ImmutableList.>of(deleteJobSettings, listJobsSettings); + initDefaults(this); + } + + protected Builder(JobServiceStubSettings settings) { + super(settings); + + deleteJobSettings = settings.deleteJobSettings.toBuilder(); + listJobsSettings = settings.listJobsSettings.toBuilder(); + + unaryMethodSettingsBuilders = + ImmutableList.>of(deleteJobSettings, listJobsSettings); + } + + private static Builder createDefault() { + Builder builder = new Builder(((ClientContext) null)); + + builder.setTransportChannelProvider(defaultTransportChannelProvider()); + builder.setCredentialsProvider(defaultCredentialsProviderBuilder().build()); + builder.setInternalHeaderProvider(defaultApiClientHeaderProviderBuilder().build()); + builder.setMtlsEndpoint(getDefaultMtlsEndpoint()); + builder.setSwitchToMtlsEndpointAllowed(true); + + return initDefaults(builder); + } + + private static Builder initDefaults(Builder builder) { + builder + .deleteJobSettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_0_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_0_params")); + + builder + .listJobsSettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_0_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_0_params")); + + return builder; + } + + /** + * Applies the given settings updater function to all of the unary API methods in this service. + * + *

Note: This method does not support applying settings to streaming methods. + */ + public Builder applyToAllUnaryMethods( + ApiFunction, Void> settingsUpdater) { + super.applyToAllUnaryMethods(unaryMethodSettingsBuilders, settingsUpdater); + return this; + } + + public ImmutableList> unaryMethodSettingsBuilders() { + return unaryMethodSettingsBuilders; + } + + /** Returns the builder for the settings used for calls to deleteJob. */ + public UnaryCallSettings.Builder deleteJobSettings() { + return deleteJobSettings; + } + + /** Returns the builder for the settings used for calls to listJobs. */ + public PagedCallSettings.Builder< + JobProto.ListJobsRequest, JobProto.JobList, ListJobsPagedResponse> + listJobsSettings() { + return listJobsSettings; + } + + @Override + public JobServiceStubSettings build() throws IOException { + return new JobServiceStubSettings(this); + } + } +} diff --git a/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/MockEchoImpl.golden b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/MockEchoImpl.golden index ae3ff13888..f8b42faff0 100644 --- a/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/MockEchoImpl.golden +++ b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/MockEchoImpl.golden @@ -293,4 +293,25 @@ public class MockEchoImpl extends EchoImplBase { Exception.class.getName()))); } } + + @Override + public void pagedExpandLegacy( + PagedExpandLegacyRequest request, StreamObserver responseObserver) { + java.lang.Object response = responses.poll(); + if (response instanceof PagedExpandResponse) { + requests.add(request); + responseObserver.onNext(((PagedExpandResponse) response)); + responseObserver.onCompleted(); + } else if (response instanceof Exception) { + responseObserver.onError(((Exception) response)); + } else { + responseObserver.onError( + new IllegalArgumentException( + String.format( + "Unrecognized response type %s for method PagedExpandLegacy, expected %s or %s", + response == null ? "null" : response.getClass().getName(), + PagedExpandResponse.class.getName(), + Exception.class.getName()))); + } + } } diff --git a/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/samples/echoclient/AsyncPagedExpandLegacy.golden b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/samples/echoclient/AsyncPagedExpandLegacy.golden new file mode 100644 index 0000000000..04fdf3b93f --- /dev/null +++ b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/samples/echoclient/AsyncPagedExpandLegacy.golden @@ -0,0 +1,51 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.showcase.v1beta1.samples; + +// [START goldensample_generated_Echo_PagedExpandLegacy_async] +import com.google.api.core.ApiFuture; +import com.google.showcase.v1beta1.EchoClient; +import com.google.showcase.v1beta1.PagedExpandLegacyRequest; +import com.google.showcase.v1beta1.PagedExpandResponse; + +public class AsyncPagedExpandLegacy { + + public static void main(String[] args) throws Exception { + asyncPagedExpandLegacy(); + } + + public static void asyncPagedExpandLegacy() throws Exception { + // This snippet has been automatically generated and should be regarded as a code template only. + // It will require modifications to work: + // - It may require correct/in-range values for request initialization. + // - It may require specifying regional endpoints when creating the service client as shown in + // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library + try (EchoClient echoClient = EchoClient.create()) { + PagedExpandLegacyRequest request = + PagedExpandLegacyRequest.newBuilder() + .setContent("content951530617") + .setMaxResults(1128457243) + .setPageToken("pageToken873572522") + .build(); + ApiFuture future = + echoClient.pagedExpandLegacyCallable().futureCall(request); + // Do something. + PagedExpandResponse response = future.get(); + } + } +} +// [END goldensample_generated_Echo_PagedExpandLegacy_async] diff --git a/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/samples/echoclient/SyncPagedExpandLegacy.golden b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/samples/echoclient/SyncPagedExpandLegacy.golden new file mode 100644 index 0000000000..51a0bad09a --- /dev/null +++ b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/samples/echoclient/SyncPagedExpandLegacy.golden @@ -0,0 +1,47 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.showcase.v1beta1.samples; + +// [START goldensample_generated_Echo_PagedExpandLegacy_sync] +import com.google.showcase.v1beta1.EchoClient; +import com.google.showcase.v1beta1.PagedExpandLegacyRequest; +import com.google.showcase.v1beta1.PagedExpandResponse; + +public class SyncPagedExpandLegacy { + + public static void main(String[] args) throws Exception { + syncPagedExpandLegacy(); + } + + public static void syncPagedExpandLegacy() throws Exception { + // This snippet has been automatically generated and should be regarded as a code template only. + // It will require modifications to work: + // - It may require correct/in-range values for request initialization. + // - It may require specifying regional endpoints when creating the service client as shown in + // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library + try (EchoClient echoClient = EchoClient.create()) { + PagedExpandLegacyRequest request = + PagedExpandLegacyRequest.newBuilder() + .setContent("content951530617") + .setMaxResults(1128457243) + .setPageToken("pageToken873572522") + .build(); + PagedExpandResponse response = echoClient.pagedExpandLegacy(request); + } + } +} +// [END goldensample_generated_Echo_PagedExpandLegacy_sync] diff --git a/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/samples/servicesettings/stub/SyncDeleteJob.golden b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/samples/servicesettings/stub/SyncDeleteJob.golden new file mode 100644 index 0000000000..db01c32cd8 --- /dev/null +++ b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/samples/servicesettings/stub/SyncDeleteJob.golden @@ -0,0 +1,55 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.bigquery.v2.stub.samples; + +// [START goldensample_generated_JobServiceStubSettings_DeleteJob_sync] +import com.google.cloud.bigquery.v2.stub.JobServiceStubSettings; +import java.time.Duration; + +public class SyncDeleteJob { + + public static void main(String[] args) throws Exception { + syncDeleteJob(); + } + + public static void syncDeleteJob() throws Exception { + // This snippet has been automatically generated and should be regarded as a code template only. + // It will require modifications to work: + // - It may require correct/in-range values for request initialization. + // - It may require specifying regional endpoints when creating the service client as shown in + // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library + JobServiceStubSettings.Builder jobServiceSettingsBuilder = JobServiceStubSettings.newBuilder(); + jobServiceSettingsBuilder + .deleteJobSettings() + .setRetrySettings( + jobServiceSettingsBuilder + .deleteJobSettings() + .getRetrySettings() + .toBuilder() + .setInitialRetryDelayDuration(Duration.ofSeconds(1)) + .setInitialRpcTimeoutDuration(Duration.ofSeconds(5)) + .setMaxAttempts(5) + .setMaxRetryDelayDuration(Duration.ofSeconds(30)) + .setMaxRpcTimeoutDuration(Duration.ofSeconds(60)) + .setRetryDelayMultiplier(1.3) + .setRpcTimeoutMultiplier(1.5) + .setTotalTimeoutDuration(Duration.ofSeconds(300)) + .build()); + JobServiceStubSettings jobServiceSettings = jobServiceSettingsBuilder.build(); + } +} +// [END goldensample_generated_JobServiceStubSettings_DeleteJob_sync] diff --git a/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/samples/servicesettings/stub/SyncListJobs.golden b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/samples/servicesettings/stub/SyncListJobs.golden new file mode 100644 index 0000000000..ba4be080cd --- /dev/null +++ b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/samples/servicesettings/stub/SyncListJobs.golden @@ -0,0 +1,55 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.bigquery.v2.stub.samples; + +// [START goldensample_generated_JobServiceStubSettings_ListJobs_sync] +import com.google.cloud.bigquery.v2.stub.JobServiceStubSettings; +import java.time.Duration; + +public class SyncListJobs { + + public static void main(String[] args) throws Exception { + syncListJobs(); + } + + public static void syncListJobs() throws Exception { + // This snippet has been automatically generated and should be regarded as a code template only. + // It will require modifications to work: + // - It may require correct/in-range values for request initialization. + // - It may require specifying regional endpoints when creating the service client as shown in + // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library + JobServiceStubSettings.Builder jobServiceSettingsBuilder = JobServiceStubSettings.newBuilder(); + jobServiceSettingsBuilder + .listJobsSettings() + .setRetrySettings( + jobServiceSettingsBuilder + .listJobsSettings() + .getRetrySettings() + .toBuilder() + .setInitialRetryDelayDuration(Duration.ofSeconds(1)) + .setInitialRpcTimeoutDuration(Duration.ofSeconds(5)) + .setMaxAttempts(5) + .setMaxRetryDelayDuration(Duration.ofSeconds(30)) + .setMaxRpcTimeoutDuration(Duration.ofSeconds(60)) + .setRetryDelayMultiplier(1.3) + .setRpcTimeoutMultiplier(1.5) + .setTotalTimeoutDuration(Duration.ofSeconds(300)) + .build()); + JobServiceStubSettings jobServiceSettings = jobServiceSettingsBuilder.build(); + } +} +// [END goldensample_generated_JobServiceStubSettings_ListJobs_sync] diff --git a/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonEchoStub.golden b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonEchoStub.golden index 18904bdfbe..85129de60b 100644 --- a/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonEchoStub.golden +++ b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonEchoStub.golden @@ -32,6 +32,7 @@ import com.google.showcase.v1beta1.EchoRequest; import com.google.showcase.v1beta1.EchoResponse; import com.google.showcase.v1beta1.ExpandRequest; import com.google.showcase.v1beta1.Object; +import com.google.showcase.v1beta1.PagedExpandLegacyRequest; import com.google.showcase.v1beta1.PagedExpandRequest; import com.google.showcase.v1beta1.PagedExpandResponse; import com.google.showcase.v1beta1.WaitMetadata; @@ -302,6 +303,42 @@ public class HttpJsonEchoStub extends EchoStub { .build()) .build(); + private static final ApiMethodDescriptor + pagedExpandLegacyMethodDescriptor = + ApiMethodDescriptor.newBuilder() + .setFullMethodName("google.showcase.v1beta1.Echo/PagedExpandLegacy") + .setHttpMethod("POST") + .setType(ApiMethodDescriptor.MethodType.UNARY) + .setRequestFormatter( + ProtoMessageRequestFormatter.newBuilder() + .setPath( + "/v1beta1/echo:pagedExpandLegacy", + request -> { + Map fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + return fields; + }) + .setQueryParamsExtractor( + request -> { + Map> fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putQueryParam(fields, "$alt", "json;enum-encoding=int"); + return fields; + }) + .setRequestBodyExtractor( + request -> + ProtoRestSerializer.create() + .toBody("*", request.toBuilder().build(), true)) + .build()) + .setResponseParser( + ProtoMessageResponseParser.newBuilder() + .setDefaultInstance(PagedExpandResponse.getDefaultInstance()) + .setDefaultTypeRegistry(typeRegistry) + .build()) + .build(); + private final UnaryCallable echoCallable; private final ServerStreamingCallable expandCallable; private final UnaryCallable pagedExpandCallable; @@ -314,6 +351,8 @@ public class HttpJsonEchoStub extends EchoStub { private final OperationCallable waitOperationCallable; private final UnaryCallable blockCallable; private final UnaryCallable collideNameCallable; + private final UnaryCallable + pagedExpandLegacyCallable; private final BackgroundResource backgroundResources; private final HttpJsonOperationsStub httpJsonOperationsStub; @@ -440,6 +479,12 @@ public class HttpJsonEchoStub extends EchoStub { .setMethodDescriptor(collideNameMethodDescriptor) .setTypeRegistry(typeRegistry) .build(); + HttpJsonCallSettings + pagedExpandLegacyTransportSettings = + HttpJsonCallSettings.newBuilder() + .setMethodDescriptor(pagedExpandLegacyMethodDescriptor) + .setTypeRegistry(typeRegistry) + .build(); this.echoCallable = callableFactory.createUnaryCallable( @@ -478,6 +523,11 @@ public class HttpJsonEchoStub extends EchoStub { this.collideNameCallable = callableFactory.createUnaryCallable( collideNameTransportSettings, settings.collideNameSettings(), clientContext); + this.pagedExpandLegacyCallable = + callableFactory.createUnaryCallable( + pagedExpandLegacyTransportSettings, + settings.pagedExpandLegacySettings(), + clientContext); this.backgroundResources = new BackgroundResourceAggregation(clientContext.getBackgroundResources()); @@ -493,6 +543,7 @@ public class HttpJsonEchoStub extends EchoStub { methodDescriptors.add(waitMethodDescriptor); methodDescriptors.add(blockMethodDescriptor); methodDescriptors.add(collideNameMethodDescriptor); + methodDescriptors.add(pagedExpandLegacyMethodDescriptor); return methodDescriptors; } @@ -551,6 +602,11 @@ public class HttpJsonEchoStub extends EchoStub { return collideNameCallable; } + @Override + public UnaryCallable pagedExpandLegacyCallable() { + return pagedExpandLegacyCallable; + } + @Override public ClientStreamingCallable collectCallable() { throw new UnsupportedOperationException( diff --git a/gapic-generator-java/src/test/java/com/google/api/generator/gapic/protoparser/ParserTest.java b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/protoparser/ParserTest.java index 6ddf533cbb..e6325ded69 100644 --- a/gapic-generator-java/src/test/java/com/google/api/generator/gapic/protoparser/ParserTest.java +++ b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/protoparser/ParserTest.java @@ -46,6 +46,7 @@ import com.google.api.version.test.ApiVersionTestingOuterClass; import com.google.auto.populate.field.AutoPopulateFieldTestingOuterClass; import com.google.bookshop.v1beta1.BookshopProto; +import com.google.cloud.bigquery.v2.JobProto; import com.google.common.collect.ImmutableList; import com.google.common.truth.Truth; import com.google.protobuf.Descriptors.FileDescriptor; @@ -154,7 +155,7 @@ void parseMethods_basic() { outputResourceNames, Transport.GRPC); - assertEquals(10, methods.size()); + assertEquals(11, methods.size()); // Methods should appear in the same order as in the protobuf file. Method echoMethod = methods.get(0); @@ -218,7 +219,7 @@ void parseMethods_basicLro() { outputResourceNames, Transport.GRPC); - assertEquals(10, methods.size()); + assertEquals(11, methods.size()); // Methods should appear in the same order as in the protobuf file. Method waitMethod = methods.get(7); @@ -373,6 +374,50 @@ void parseMethodSignatures_basic() { argument); } + @Test + void parsePageSizeFieldName_basic() { + MethodDescriptor methodDescriptor = echoService.getMethods().get(5); + assertEquals("PagedExpand", methodDescriptor.getName()); + Map messageTypes = Parser.parseMessages(echoFileDescriptor); + String pageSizeFieldName = + Parser.parsePageSizeFieldName(methodDescriptor, messageTypes, Transport.GRPC); + assertEquals("page_size", pageSizeFieldName); + } + + @Test + void parsePageSizeFieldName_grpcLegacy() { + MethodDescriptor methodDescriptor = echoService.getMethods().get(10); + assertEquals("PagedExpandLegacy", methodDescriptor.getName()); + Map messageTypes = Parser.parseMessages(echoFileDescriptor); + String pageSizeFieldName = + Parser.parsePageSizeFieldName(methodDescriptor, messageTypes, Transport.GRPC); + assertNull(pageSizeFieldName); + } + + @Test + void parsePageSizeFieldName_restLegacy() { + MethodDescriptor methodDescriptor = echoService.getMethods().get(10); + assertEquals("PagedExpandLegacy", methodDescriptor.getName()); + Map messageTypes = Parser.parseMessages(echoFileDescriptor); + String pageSizeFieldName = + Parser.parsePageSizeFieldName(methodDescriptor, messageTypes, Transport.REST); + assertEquals("max_results", pageSizeFieldName); + } + + @Test + void parsePageSizeFieldName_bigqueryLegacy() { + FileDescriptor bqJobFileDescriptor = JobProto.getDescriptor(); + ServiceDescriptor jobService = bqJobFileDescriptor.getServices().get(0); + MethodDescriptor deleteJobMethodDescriptor = jobService.getMethods().get(0); + assertEquals("DeleteJob", deleteJobMethodDescriptor.getName()); + MethodDescriptor listJobsMethodDescriptor = jobService.getMethods().get(1); + assertEquals("ListJobs", listJobsMethodDescriptor.getName()); + Map messageTypes = Parser.parseMessages(bqJobFileDescriptor); + String pageSizeFieldName = + Parser.parsePageSizeFieldName(listJobsMethodDescriptor, messageTypes, Transport.GRPC); + assertEquals("max_results", pageSizeFieldName); + } + @Test void parseMessagesAndResourceNames_update() { FileDescriptor lockerServiceFileDescriptor = LockerProto.getDescriptor(); diff --git a/gapic-generator-java/src/test/java/com/google/api/generator/test/protoloader/TestProtoLoader.java b/gapic-generator-java/src/test/java/com/google/api/generator/test/protoloader/TestProtoLoader.java index 1030e8231e..0e4148110e 100644 --- a/gapic-generator-java/src/test/java/com/google/api/generator/test/protoloader/TestProtoLoader.java +++ b/gapic-generator-java/src/test/java/com/google/api/generator/test/protoloader/TestProtoLoader.java @@ -31,6 +31,7 @@ import com.google.api.version.test.ApiVersionTestingOuterClass; import com.google.auto.populate.field.AutoPopulateFieldTestingOuterClass; import com.google.bookshop.v1beta1.BookshopProto; +import com.google.cloud.bigquery.v2.JobProto; import com.google.explicit.dynamic.routing.header.ExplicitDynamicRoutingHeaderTestingOuterClass; import com.google.logging.v2.LogEntryProto; import com.google.logging.v2.LoggingConfigProto; @@ -86,7 +87,7 @@ public static TestProtoLoader instance() { public GapicContext parseDeprecatedService() { FileDescriptor fileDescriptor = DeprecatedServiceOuterClass.getDescriptor(); ServiceDescriptor serviceDescriptor = fileDescriptor.getServices().get(0); - assertEquals(serviceDescriptor.getName(), "DeprecatedService"); + assertEquals("DeprecatedService", serviceDescriptor.getName()); Map messageTypes = Parser.parseMessages(fileDescriptor); Map resourceNames = new HashMap<>(); @@ -114,7 +115,7 @@ public GapicContext parseDeprecatedService() { public GapicContext parseBookshopService() { FileDescriptor fileDescriptor = BookshopProto.getDescriptor(); ServiceDescriptor serviceDescriptor = fileDescriptor.getServices().get(0); - assertEquals(serviceDescriptor.getName(), "Bookshop"); + assertEquals("Bookshop", serviceDescriptor.getName()); Map messageTypes = Parser.parseMessages(fileDescriptor); Map resourceNames = new HashMap<>(); @@ -142,7 +143,7 @@ public GapicContext parseBookshopService() { public GapicContext parseNestedMessage() { FileDescriptor fileDescriptor = TypesTestingProto.getDescriptor(); ServiceDescriptor serviceDescriptor = fileDescriptor.getServices().get(0); - assertEquals(serviceDescriptor.getName(), "NestedMessageService"); + assertEquals("NestedMessageService", serviceDescriptor.getName()); Map messageTypes = Parser.parseMessages(fileDescriptor); FileDescriptor messageFileDescriptor = NestedMessageProto.getDescriptor(); @@ -166,7 +167,7 @@ public GapicContext parseNestedMessage() { public GapicContext parseShowcaseEcho() { FileDescriptor echoFileDescriptor = EchoOuterClass.getDescriptor(); ServiceDescriptor echoServiceDescriptor = echoFileDescriptor.getServices().get(0); - assertEquals(echoServiceDescriptor.getName(), "Echo"); + assertEquals("Echo", echoServiceDescriptor.getName()); String serviceYamlFilename = "echo_v1beta1.yaml"; Path serviceYamlPath = Paths.get(testFilesDirectory, serviceYamlFilename); @@ -207,7 +208,7 @@ public GapicContext parseShowcaseEcho() { public GapicContext parseShowcaseIdentity() { FileDescriptor fileDescriptor = IdentityOuterClass.getDescriptor(); ServiceDescriptor identityService = fileDescriptor.getServices().get(0); - assertEquals(identityService.getName(), "Identity"); + assertEquals("Identity", identityService.getName()); Map messageTypes = Parser.parseMessages(fileDescriptor); Map resourceNames = Parser.parseResourceNames(fileDescriptor); @@ -228,7 +229,7 @@ public GapicContext parseShowcaseIdentity() { public GapicContext parseShowcaseMessaging() { FileDescriptor fileDescriptor = MessagingOuterClass.getDescriptor(); ServiceDescriptor messagingService = fileDescriptor.getServices().get(0); - assertEquals(messagingService.getName(), "Messaging"); + assertEquals("Messaging", messagingService.getName()); Map messageTypes = Parser.parseMessages(fileDescriptor); Map resourceNames = Parser.parseResourceNames(fileDescriptor); @@ -249,7 +250,7 @@ public GapicContext parseShowcaseMessaging() { public GapicContext parseShowcaseTesting() { FileDescriptor testingFileDescriptor = TestingOuterClass.getDescriptor(); ServiceDescriptor testingService = testingFileDescriptor.getServices().get(0); - assertEquals(testingService.getName(), "Testing"); + assertEquals("Testing", testingService.getName()); Map messageTypes = Parser.parseMessages(testingFileDescriptor); Map resourceNames = Parser.parseResourceNames(testingFileDescriptor); @@ -275,7 +276,7 @@ public GapicContext parseExplicitDynamicRoutingHeaderTesting() { FileDescriptor testingFileDescriptor = ExplicitDynamicRoutingHeaderTestingOuterClass.getDescriptor(); ServiceDescriptor testingService = testingFileDescriptor.getServices().get(0); - assertEquals(testingService.getName(), "ExplicitDynamicRoutingHeaderTesting"); + assertEquals("ExplicitDynamicRoutingHeaderTesting", testingService.getName()); Map messageTypes = Parser.parseMessages(testingFileDescriptor); Map resourceNames = Parser.parseResourceNames(testingFileDescriptor); @@ -300,7 +301,7 @@ public GapicContext parseExplicitDynamicRoutingHeaderTesting() { public GapicContext parseApiVersionTesting() { FileDescriptor testingFileDescriptor = ApiVersionTestingOuterClass.getDescriptor(); ServiceDescriptor testingService = testingFileDescriptor.getServices().get(0); - assertEquals(testingService.getName(), "EchoWithVersion"); + assertEquals("EchoWithVersion", testingService.getName()); Map messageTypes = Parser.parseMessages(testingFileDescriptor); Map resourceNames = Parser.parseResourceNames(testingFileDescriptor); @@ -333,7 +334,7 @@ public GapicContext parseAutoPopulateFieldTesting() { AutoPopulateFieldTestingOuterClass.getDescriptor(); ServiceDescriptor autopopulationServiceDescriptor = autopopulationFileDescriptor.getServices().get(0); - assertEquals(autopopulationServiceDescriptor.getName(), "AutoPopulateFieldTesting"); + assertEquals("AutoPopulateFieldTesting", autopopulationServiceDescriptor.getName()); String serviceYamlFilename = "auto_populate_field_testing.yaml"; Path serviceYamlPath = Paths.get(testFilesDirectory, serviceYamlFilename); @@ -451,7 +452,7 @@ public GapicContext parsePubSubPublisher() { public GapicContext parseLogging() { FileDescriptor serviceFileDescriptor = LoggingProto.getDescriptor(); ServiceDescriptor serviceDescriptor = serviceFileDescriptor.getServices().get(0); - assertEquals(serviceDescriptor.getName(), "LoggingServiceV2"); + assertEquals("LoggingServiceV2", serviceDescriptor.getName()); List protoFiles = Arrays.asList( @@ -506,7 +507,7 @@ public GapicContext parseLogging() { public GapicContext parseCallabeNameType() { FileDescriptor serviceFileDescriptor = CallableNameType.getDescriptor(); ServiceDescriptor serviceDescriptor = serviceFileDescriptor.getServices().get(0); - assertEquals(serviceDescriptor.getName(), "CallableNameTypeService"); + assertEquals("CallableNameTypeService", serviceDescriptor.getName()); List protoFiles = Collections.singletonList(serviceFileDescriptor); @@ -539,6 +540,38 @@ public GapicContext parseCallabeNameType() { .build(); } + public GapicContext parseBigqueryService() { + FileDescriptor bigqueryFileDescriptor = JobProto.getDescriptor(); + ServiceDescriptor biqqueryServiceDescriptor = bigqueryFileDescriptor.getServices().get(0); + assertEquals("JobService", biqqueryServiceDescriptor.getName()); + + Map messageTypes = Parser.parseMessages(bigqueryFileDescriptor); + Map resourceNames = Parser.parseResourceNames(bigqueryFileDescriptor); + Set outputResourceNames = new HashSet<>(); + List services = + Parser.parseService( + bigqueryFileDescriptor, + messageTypes, + resourceNames, + Optional.empty(), + outputResourceNames); + + String jsonFilename = "bigquery_v2_service_config.json"; + Path jsonPath = Paths.get(testFilesDirectory, jsonFilename); + Optional configOpt = ServiceConfigParser.parse(jsonPath.toString()); + assertTrue(configOpt.isPresent()); + GapicServiceConfig config = configOpt.get(); + + return GapicContext.builder() + .setMessages(messageTypes) + .setResourceNames(resourceNames) + .setServices(services) + .setServiceConfig(config) + .setHelperResourceNames(outputResourceNames) + .setTransport(transport) + .build(); + } + public String getTestFilesDirectory() { return testFilesDirectory; } diff --git a/gapic-generator-java/src/test/proto/bigquery_jobs.proto b/gapic-generator-java/src/test/proto/bigquery_jobs.proto new file mode 100644 index 0000000000..9d6da3c8d9 --- /dev/null +++ b/gapic-generator-java/src/test/proto/bigquery_jobs.proto @@ -0,0 +1,112 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.cloud.bigquery.v2; + +import "google/api/annotations.proto"; +import "google/api/client.proto"; +import "google/api/field_behavior.proto"; +import "google/api/resource.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/struct.proto"; +import "google/protobuf/wrappers.proto"; + +option java_outer_classname = "JobProto"; +option java_package = "com.google.cloud.bigquery.v2"; + +service JobService { + option (google.api.default_host) = "bigquery.googleapis.com"; + option (google.api.oauth_scopes) = + "https://www.googleapis.com/auth/bigquery," + "https://www.googleapis.com/auth/cloud-platform," + "https://www.googleapis.com/auth/cloud-platform.read-only," + "https://www.googleapis.com/auth/devstorage.full_control," + "https://www.googleapis.com/auth/devstorage.read_only," + "https://www.googleapis.com/auth/devstorage.read_write"; + + // Requests the deletion of the metadata of a job. This call returns when the + // job's metadata is deleted. + rpc DeleteJob(DeleteJobRequest) returns (google.protobuf.Empty) { + option (google.api.http) = { + delete: "/bigquery/v2/projects/{project_id=*}/jobs/{job_id=*}/delete" + }; + } + + // Lists all jobs that you started in the specified project. Job information + // is available for a six month period after creation. The job list is sorted + // in reverse chronological order, by job creation time. Requires the Can View + // project role, or the Is Owner project role if you set the allUsers + // property. + rpc ListJobs(ListJobsRequest) returns (JobList) { + option (google.api.http) = { + get: "/bigquery/v2/projects/{project_id=*}/jobs" + }; + } +} + +// Simplified BigQuery Jobs service ListJobsRequest for testing. +message ListJobsRequest { + // Project ID of the jobs to list. + string project_id = 1; + + // The maximum number of results to return in a single response page. + // Leverage the page tokens to iterate through the entire collection. + google.protobuf.Int32Value max_results = 3; + + // Page token, returned by a previous call, to request the next page of + // results. + string page_token = 6; +} + +// Describes the format of a jobs deletion request. +message DeleteJobRequest { + // Required. Project ID of the job for which metadata is to be deleted. + string project_id = 1 [(google.api.field_behavior) = REQUIRED]; + + // Required. Job ID of the job for which metadata is to be deleted. If this is + // a parent job which has child jobs, the metadata from all child jobs will be + // deleted as well. Direct deletion of the metadata of child jobs is not + // allowed. + string job_id = 2 [(google.api.field_behavior) = REQUIRED]; + + // The geographic location of the job. Required. + // + // For more information, see how to + // [specify + // locations](https://cloud.google.com/bigquery/docs/locations#specify_locations). + string location = 3; +} + +// Simplified ListFormatJob for testing. +message ListFormatJob { + // Unique opaque ID of the job. + string id = 1; +} + +// Simplified JobList response for testing. +message JobList { + // A hash of this page of results. + string etag = 1; + + // The resource type of the response. + string kind = 2; + + // A token to request the next page of results. + string next_page_token = 3; + + // List of jobs that were requested. + repeated ListFormatJob jobs = 4; +} \ No newline at end of file diff --git a/gapic-generator-java/src/test/proto/echo.proto b/gapic-generator-java/src/test/proto/echo.proto index 361e661459..28052e26c6 100644 --- a/gapic-generator-java/src/test/proto/echo.proto +++ b/gapic-generator-java/src/test/proto/echo.proto @@ -140,6 +140,16 @@ service Echo { body: "*" }; } + + // This is similar to the PagedExpand except that it uses + // max_results instead of page_size, as some legacy APIs still + // do. New APIs should NOT use this pattern. + rpc PagedExpandLegacy(PagedExpandLegacyRequest) returns (PagedExpandResponse) { + option (google.api.http) = { + post: "/v1beta1/echo:pagedExpandLegacy" + body: "*" + }; + } } // A severity enum used to test enum capabilities in GAPIC surfaces @@ -295,3 +305,19 @@ message BlockResponse { // here. string content = 1; } + +// The request for the PagedExpandLegacy method. This is a pattern used by some legacy APIs. New +// APIs should NOT use this pattern, but rather something like PagedExpandRequest which conforms to +// aip.dev/158. +message PagedExpandLegacyRequest { + // The string to expand. + string content = 1 [(google.api.field_behavior) = REQUIRED]; + + // The number of words to returned in each page. + // (-- aip.dev/not-precedent: This is a legacy, non-standard pattern that + // violates aip.dev/158. Ordinarily, this should be page_size. --) + int32 max_results = 2; + + // The position of the page to be returned. + string page_token = 3; +} diff --git a/gapic-generator-java/src/test/resources/bigquery_v2_service_config.json b/gapic-generator-java/src/test/resources/bigquery_v2_service_config.json new file mode 100644 index 0000000000..8bc947af4e --- /dev/null +++ b/gapic-generator-java/src/test/resources/bigquery_v2_service_config.json @@ -0,0 +1,10 @@ +{ + "methodConfig": [ + { + "name": [ + {"service": "google.cloud.bigquery.v2.JobService"} + ], + "timeout": "5s" + } + ] +}