diff --git a/README.md b/README.md index ef0647a5..49fdb3bc 100644 --- a/README.md +++ b/README.md @@ -56,13 +56,13 @@ implementation 'com.google.cloud:google-cloud-billingbudgets' If you are using Gradle without BOM, add this to your dependencies ```Groovy -implementation 'com.google.cloud:google-cloud-billingbudgets:2.2.0' +implementation 'com.google.cloud:google-cloud-billingbudgets:2.2.1' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "google-cloud-billingbudgets" % "2.2.0" +libraryDependencies += "com.google.cloud" % "google-cloud-billingbudgets" % "2.2.1" ``` ## Authentication diff --git a/google-cloud-billingbudgets/pom.xml b/google-cloud-billingbudgets/pom.xml index ccc9f704..e41a0591 100644 --- a/google-cloud-billingbudgets/pom.xml +++ b/google-cloud-billingbudgets/pom.xml @@ -62,6 +62,10 @@ com.google.api gax-grpc + + com.google.api + gax-httpjson + org.threeten threetenbp @@ -84,12 +88,24 @@ test + + com.google.api + gax + testlib + test + com.google.api gax-grpc testlib test + + com.google.api + gax-httpjson + testlib + test + diff --git a/google-cloud-billingbudgets/src/main/java/com/google/cloud/billing/budgets/v1/BudgetServiceClient.java b/google-cloud-billingbudgets/src/main/java/com/google/cloud/billing/budgets/v1/BudgetServiceClient.java index f702ef68..8b79fa1d 100644 --- a/google-cloud-billingbudgets/src/main/java/com/google/cloud/billing/budgets/v1/BudgetServiceClient.java +++ b/google-cloud-billingbudgets/src/main/java/com/google/cloud/billing/budgets/v1/BudgetServiceClient.java @@ -100,6 +100,20 @@ * BudgetServiceClient budgetServiceClient = BudgetServiceClient.create(budgetServiceSettings); * } * + *

To use REST (HTTP1.1/JSON) transport (instead of gRPC) for sending and receiving requests over + * the wire: + * + *

{@code
+ * // This snippet has been automatically generated for illustrative purposes only.
+ * // It may require modifications to work in your environment.
+ * BudgetServiceSettings budgetServiceSettings =
+ *     BudgetServiceSettings.newBuilder()
+ *         .setTransportChannelProvider(
+ *             BudgetServiceSettings.defaultHttpJsonTransportProviderBuilder().build())
+ *         .build();
+ * BudgetServiceClient budgetServiceClient = BudgetServiceClient.create(budgetServiceSettings);
+ * }
+ * *

Please refer to the GitHub repository's samples for more quickstart code snippets. */ @Generated("by gapic-generator-java") diff --git a/google-cloud-billingbudgets/src/main/java/com/google/cloud/billing/budgets/v1/BudgetServiceSettings.java b/google-cloud-billingbudgets/src/main/java/com/google/cloud/billing/budgets/v1/BudgetServiceSettings.java index 6f7ebe1e..acaff4a1 100644 --- a/google-cloud-billingbudgets/src/main/java/com/google/cloud/billing/budgets/v1/BudgetServiceSettings.java +++ b/google-cloud-billingbudgets/src/main/java/com/google/cloud/billing/budgets/v1/BudgetServiceSettings.java @@ -23,6 +23,7 @@ import com.google.api.gax.core.GoogleCredentialsProvider; import com.google.api.gax.core.InstantiatingExecutorProvider; import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider; +import com.google.api.gax.httpjson.InstantiatingHttpJsonChannelProvider; import com.google.api.gax.rpc.ApiClientHeaderProvider; import com.google.api.gax.rpc.ClientContext; import com.google.api.gax.rpc.ClientSettings; @@ -123,11 +124,18 @@ public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilde return BudgetServiceStubSettings.defaultCredentialsProviderBuilder(); } - /** Returns a builder for the default ChannelProvider for this service. */ + /** Returns a builder for the default gRPC ChannelProvider for this service. */ public static InstantiatingGrpcChannelProvider.Builder defaultGrpcTransportProviderBuilder() { return BudgetServiceStubSettings.defaultGrpcTransportProviderBuilder(); } + /** Returns a builder for the default REST ChannelProvider for this service. */ + @BetaApi + public static InstantiatingHttpJsonChannelProvider.Builder + defaultHttpJsonTransportProviderBuilder() { + return BudgetServiceStubSettings.defaultHttpJsonTransportProviderBuilder(); + } + public static TransportChannelProvider defaultTransportChannelProvider() { return BudgetServiceStubSettings.defaultTransportChannelProvider(); } @@ -137,11 +145,17 @@ public static ApiClientHeaderProvider.Builder defaultApiClientHeaderProviderBuil return BudgetServiceStubSettings.defaultApiClientHeaderProviderBuilder(); } - /** Returns a new builder for this class. */ + /** Returns a new gRPC builder for this class. */ public static Builder newBuilder() { return Builder.createDefault(); } + /** Returns a new REST builder for this class. */ + @BetaApi + public static Builder newHttpJsonBuilder() { + return Builder.createHttpJsonDefault(); + } + /** Returns a new builder for this class. */ public static Builder newBuilder(ClientContext clientContext) { return new Builder(clientContext); @@ -179,6 +193,11 @@ private static Builder createDefault() { return new Builder(BudgetServiceStubSettings.newBuilder()); } + @BetaApi + private static Builder createHttpJsonDefault() { + return new Builder(BudgetServiceStubSettings.newHttpJsonBuilder()); + } + public BudgetServiceStubSettings.Builder getStubSettingsBuilder() { return ((BudgetServiceStubSettings.Builder) getStubSettings()); } diff --git a/google-cloud-billingbudgets/src/main/java/com/google/cloud/billing/budgets/v1/stub/BudgetServiceStubSettings.java b/google-cloud-billingbudgets/src/main/java/com/google/cloud/billing/budgets/v1/stub/BudgetServiceStubSettings.java index 6ad457c8..65474976 100644 --- a/google-cloud-billingbudgets/src/main/java/com/google/cloud/billing/budgets/v1/stub/BudgetServiceStubSettings.java +++ b/google-cloud-billingbudgets/src/main/java/com/google/cloud/billing/budgets/v1/stub/BudgetServiceStubSettings.java @@ -27,6 +27,9 @@ 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.httpjson.GaxHttpJsonProperties; +import com.google.api.gax.httpjson.HttpJsonTransportChannel; +import com.google.api.gax.httpjson.InstantiatingHttpJsonChannelProvider; import com.google.api.gax.retrying.RetrySettings; import com.google.api.gax.rpc.ApiCallContext; import com.google.api.gax.rpc.ApiClientHeaderProvider; @@ -193,6 +196,11 @@ public BudgetServiceStub createStub() throws IOException { .equals(GrpcTransportChannel.getGrpcTransportName())) { return GrpcBudgetServiceStub.create(this); } + if (getTransportChannelProvider() + .getTransportName() + .equals(HttpJsonTransportChannel.getHttpJsonTransportName())) { + return HttpJsonBudgetServiceStub.create(this); + } throw new UnsupportedOperationException( String.format( "Transport not supported: %s", getTransportChannelProvider().getTransportName())); @@ -225,18 +233,25 @@ public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilde .setUseJwtAccessWithScope(true); } - /** Returns a builder for the default ChannelProvider for this service. */ + /** Returns a builder for the default gRPC ChannelProvider for this service. */ public static InstantiatingGrpcChannelProvider.Builder defaultGrpcTransportProviderBuilder() { return InstantiatingGrpcChannelProvider.newBuilder() .setMaxInboundMessageSize(Integer.MAX_VALUE); } + /** Returns a builder for the default REST ChannelProvider for this service. */ + @BetaApi + public static InstantiatingHttpJsonChannelProvider.Builder + defaultHttpJsonTransportProviderBuilder() { + return InstantiatingHttpJsonChannelProvider.newBuilder(); + } + public static TransportChannelProvider defaultTransportChannelProvider() { return defaultGrpcTransportProviderBuilder().build(); } @BetaApi("The surface for customizing headers is not stable yet and may change in the future.") - public static ApiClientHeaderProvider.Builder defaultApiClientHeaderProviderBuilder() { + public static ApiClientHeaderProvider.Builder defaultGrpcApiClientHeaderProviderBuilder() { return ApiClientHeaderProvider.newBuilder() .setGeneratedLibToken( "gapic", GaxProperties.getLibraryVersion(BudgetServiceStubSettings.class)) @@ -244,11 +259,30 @@ public static ApiClientHeaderProvider.Builder defaultApiClientHeaderProviderBuil GaxGrpcProperties.getGrpcTokenName(), GaxGrpcProperties.getGrpcVersion()); } - /** Returns a new builder for this class. */ + @BetaApi("The surface for customizing headers is not stable yet and may change in the future.") + public static ApiClientHeaderProvider.Builder defaultHttpJsonApiClientHeaderProviderBuilder() { + return ApiClientHeaderProvider.newBuilder() + .setGeneratedLibToken( + "gapic", GaxProperties.getLibraryVersion(BudgetServiceStubSettings.class)) + .setTransportToken( + GaxHttpJsonProperties.getHttpJsonTokenName(), + GaxHttpJsonProperties.getHttpJsonVersion()); + } + + public static ApiClientHeaderProvider.Builder defaultApiClientHeaderProviderBuilder() { + return BudgetServiceStubSettings.defaultGrpcApiClientHeaderProviderBuilder(); + } + + /** Returns a new gRPC builder for this class. */ public static Builder newBuilder() { return Builder.createDefault(); } + /** Returns a new REST builder for this class. */ + public static Builder newHttpJsonBuilder() { + return Builder.createHttpJsonDefault(); + } + /** Returns a new builder for this class. */ public static Builder newBuilder(ClientContext clientContext) { return new Builder(clientContext); @@ -376,6 +410,19 @@ private static Builder createDefault() { return initDefaults(builder); } + private static Builder createHttpJsonDefault() { + Builder builder = new Builder(((ClientContext) null)); + + builder.setTransportChannelProvider(defaultHttpJsonTransportProviderBuilder().build()); + builder.setCredentialsProvider(defaultCredentialsProviderBuilder().build()); + builder.setInternalHeaderProvider(defaultHttpJsonApiClientHeaderProviderBuilder().build()); + builder.setEndpoint(getDefaultEndpoint()); + builder.setMtlsEndpoint(getDefaultMtlsEndpoint()); + builder.setSwitchToMtlsEndpointAllowed(true); + + return initDefaults(builder); + } + private static Builder initDefaults(Builder builder) { builder .createBudgetSettings() diff --git a/google-cloud-billingbudgets/src/main/java/com/google/cloud/billing/budgets/v1/stub/HttpJsonBudgetServiceCallableFactory.java b/google-cloud-billingbudgets/src/main/java/com/google/cloud/billing/budgets/v1/stub/HttpJsonBudgetServiceCallableFactory.java new file mode 100644 index 00000000..bf786f60 --- /dev/null +++ b/google-cloud-billingbudgets/src/main/java/com/google/cloud/billing/budgets/v1/stub/HttpJsonBudgetServiceCallableFactory.java @@ -0,0 +1,105 @@ +/* + * Copyright 2022 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.billing.budgets.v1.stub; + +import com.google.api.core.BetaApi; +import com.google.api.gax.httpjson.HttpJsonCallSettings; +import com.google.api.gax.httpjson.HttpJsonCallableFactory; +import com.google.api.gax.httpjson.HttpJsonOperationSnapshotCallable; +import com.google.api.gax.httpjson.HttpJsonStubCallableFactory; +import com.google.api.gax.httpjson.longrunning.stub.OperationsStub; +import com.google.api.gax.rpc.BatchingCallSettings; +import com.google.api.gax.rpc.ClientContext; +import com.google.api.gax.rpc.OperationCallSettings; +import com.google.api.gax.rpc.OperationCallable; +import com.google.api.gax.rpc.PagedCallSettings; +import com.google.api.gax.rpc.ServerStreamingCallSettings; +import com.google.api.gax.rpc.ServerStreamingCallable; +import com.google.api.gax.rpc.UnaryCallSettings; +import com.google.api.gax.rpc.UnaryCallable; +import com.google.longrunning.Operation; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * REST callable factory implementation for the BudgetService service API. + * + *

This class is for advanced usage. + */ +@Generated("by gapic-generator-java") +@BetaApi +public class HttpJsonBudgetServiceCallableFactory + implements HttpJsonStubCallableFactory { + + @Override + public UnaryCallable createUnaryCallable( + HttpJsonCallSettings httpJsonCallSettings, + UnaryCallSettings callSettings, + ClientContext clientContext) { + return HttpJsonCallableFactory.createUnaryCallable( + httpJsonCallSettings, callSettings, clientContext); + } + + @Override + public + UnaryCallable createPagedCallable( + HttpJsonCallSettings httpJsonCallSettings, + PagedCallSettings callSettings, + ClientContext clientContext) { + return HttpJsonCallableFactory.createPagedCallable( + httpJsonCallSettings, callSettings, clientContext); + } + + @Override + public UnaryCallable createBatchingCallable( + HttpJsonCallSettings httpJsonCallSettings, + BatchingCallSettings callSettings, + ClientContext clientContext) { + return HttpJsonCallableFactory.createBatchingCallable( + httpJsonCallSettings, callSettings, clientContext); + } + + @BetaApi( + "The surface for long-running operations is not stable yet and may change in the future.") + @Override + public + OperationCallable createOperationCallable( + HttpJsonCallSettings httpJsonCallSettings, + OperationCallSettings callSettings, + ClientContext clientContext, + OperationsStub operationsStub) { + UnaryCallable innerCallable = + HttpJsonCallableFactory.createBaseUnaryCallable( + httpJsonCallSettings, callSettings.getInitialCallSettings(), clientContext); + HttpJsonOperationSnapshotCallable initialCallable = + new HttpJsonOperationSnapshotCallable( + innerCallable, + httpJsonCallSettings.getMethodDescriptor().getOperationSnapshotFactory()); + return HttpJsonCallableFactory.createOperationCallable( + callSettings, clientContext, operationsStub.longRunningClient(), initialCallable); + } + + @Override + public + ServerStreamingCallable createServerStreamingCallable( + HttpJsonCallSettings httpJsonCallSettings, + ServerStreamingCallSettings callSettings, + ClientContext clientContext) { + return HttpJsonCallableFactory.createServerStreamingCallable( + httpJsonCallSettings, callSettings, clientContext); + } +} diff --git a/google-cloud-billingbudgets/src/main/java/com/google/cloud/billing/budgets/v1/stub/HttpJsonBudgetServiceStub.java b/google-cloud-billingbudgets/src/main/java/com/google/cloud/billing/budgets/v1/stub/HttpJsonBudgetServiceStub.java new file mode 100644 index 00000000..6cbd51bf --- /dev/null +++ b/google-cloud-billingbudgets/src/main/java/com/google/cloud/billing/budgets/v1/stub/HttpJsonBudgetServiceStub.java @@ -0,0 +1,408 @@ +/* + * Copyright 2022 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.billing.budgets.v1.stub; + +import static com.google.cloud.billing.budgets.v1.BudgetServiceClient.ListBudgetsPagedResponse; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.api.gax.core.BackgroundResource; +import com.google.api.gax.core.BackgroundResourceAggregation; +import com.google.api.gax.httpjson.ApiMethodDescriptor; +import com.google.api.gax.httpjson.HttpJsonCallSettings; +import com.google.api.gax.httpjson.HttpJsonStubCallableFactory; +import com.google.api.gax.httpjson.ProtoMessageRequestFormatter; +import com.google.api.gax.httpjson.ProtoMessageResponseParser; +import com.google.api.gax.httpjson.ProtoRestSerializer; +import com.google.api.gax.rpc.ClientContext; +import com.google.api.gax.rpc.UnaryCallable; +import com.google.cloud.billing.budgets.v1.Budget; +import com.google.cloud.billing.budgets.v1.CreateBudgetRequest; +import com.google.cloud.billing.budgets.v1.DeleteBudgetRequest; +import com.google.cloud.billing.budgets.v1.GetBudgetRequest; +import com.google.cloud.billing.budgets.v1.ListBudgetsRequest; +import com.google.cloud.billing.budgets.v1.ListBudgetsResponse; +import com.google.cloud.billing.budgets.v1.UpdateBudgetRequest; +import com.google.protobuf.Empty; +import com.google.protobuf.TypeRegistry; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * REST stub implementation for the BudgetService service API. + * + *

This class is for advanced usage and reflects the underlying API directly. + */ +@Generated("by gapic-generator-java") +@BetaApi +public class HttpJsonBudgetServiceStub extends BudgetServiceStub { + private static final TypeRegistry typeRegistry = TypeRegistry.newBuilder().build(); + + private static final ApiMethodDescriptor + createBudgetMethodDescriptor = + ApiMethodDescriptor.newBuilder() + .setFullMethodName("google.cloud.billing.budgets.v1.BudgetService/CreateBudget") + .setHttpMethod("POST") + .setType(ApiMethodDescriptor.MethodType.UNARY) + .setRequestFormatter( + ProtoMessageRequestFormatter.newBuilder() + .setPath( + "/v1/{parent=billingAccounts/*}/budgets", + request -> { + Map fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putPathParam(fields, "parent", request.getParent()); + return fields; + }) + .setQueryParamsExtractor( + request -> { + Map> fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + return fields; + }) + .setRequestBodyExtractor( + request -> + ProtoRestSerializer.create().toBody("budget", request.getBudget())) + .build()) + .setResponseParser( + ProtoMessageResponseParser.newBuilder() + .setDefaultInstance(Budget.getDefaultInstance()) + .setDefaultTypeRegistry(typeRegistry) + .build()) + .build(); + + private static final ApiMethodDescriptor + updateBudgetMethodDescriptor = + ApiMethodDescriptor.newBuilder() + .setFullMethodName("google.cloud.billing.budgets.v1.BudgetService/UpdateBudget") + .setHttpMethod("PATCH") + .setType(ApiMethodDescriptor.MethodType.UNARY) + .setRequestFormatter( + ProtoMessageRequestFormatter.newBuilder() + .setPath( + "/v1/{budget.name=billingAccounts/*/budgets/*}", + request -> { + Map fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putPathParam( + fields, "budget.name", request.getBudget().getName()); + return fields; + }) + .setQueryParamsExtractor( + request -> { + Map> fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putQueryParam(fields, "updateMask", request.getUpdateMask()); + return fields; + }) + .setRequestBodyExtractor( + request -> + ProtoRestSerializer.create().toBody("budget", request.getBudget())) + .build()) + .setResponseParser( + ProtoMessageResponseParser.newBuilder() + .setDefaultInstance(Budget.getDefaultInstance()) + .setDefaultTypeRegistry(typeRegistry) + .build()) + .build(); + + private static final ApiMethodDescriptor getBudgetMethodDescriptor = + ApiMethodDescriptor.newBuilder() + .setFullMethodName("google.cloud.billing.budgets.v1.BudgetService/GetBudget") + .setHttpMethod("GET") + .setType(ApiMethodDescriptor.MethodType.UNARY) + .setRequestFormatter( + ProtoMessageRequestFormatter.newBuilder() + .setPath( + "/v1/{name=billingAccounts/*/budgets/*}", + request -> { + Map fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putPathParam(fields, "name", request.getName()); + return fields; + }) + .setQueryParamsExtractor( + request -> { + Map> fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + return fields; + }) + .setRequestBodyExtractor(request -> null) + .build()) + .setResponseParser( + ProtoMessageResponseParser.newBuilder() + .setDefaultInstance(Budget.getDefaultInstance()) + .setDefaultTypeRegistry(typeRegistry) + .build()) + .build(); + + private static final ApiMethodDescriptor + listBudgetsMethodDescriptor = + ApiMethodDescriptor.newBuilder() + .setFullMethodName("google.cloud.billing.budgets.v1.BudgetService/ListBudgets") + .setHttpMethod("GET") + .setType(ApiMethodDescriptor.MethodType.UNARY) + .setRequestFormatter( + ProtoMessageRequestFormatter.newBuilder() + .setPath( + "/v1/{parent=billingAccounts/*}/budgets", + request -> { + Map fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putPathParam(fields, "parent", request.getParent()); + return fields; + }) + .setQueryParamsExtractor( + request -> { + Map> fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putQueryParam(fields, "pageSize", request.getPageSize()); + serializer.putQueryParam(fields, "pageToken", request.getPageToken()); + return fields; + }) + .setRequestBodyExtractor(request -> null) + .build()) + .setResponseParser( + ProtoMessageResponseParser.newBuilder() + .setDefaultInstance(ListBudgetsResponse.getDefaultInstance()) + .setDefaultTypeRegistry(typeRegistry) + .build()) + .build(); + + private static final ApiMethodDescriptor + deleteBudgetMethodDescriptor = + ApiMethodDescriptor.newBuilder() + .setFullMethodName("google.cloud.billing.budgets.v1.BudgetService/DeleteBudget") + .setHttpMethod("DELETE") + .setType(ApiMethodDescriptor.MethodType.UNARY) + .setRequestFormatter( + ProtoMessageRequestFormatter.newBuilder() + .setPath( + "/v1/{name=billingAccounts/*/budgets/*}", + request -> { + Map fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putPathParam(fields, "name", request.getName()); + return fields; + }) + .setQueryParamsExtractor( + request -> { + Map> fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + return fields; + }) + .setRequestBodyExtractor(request -> null) + .build()) + .setResponseParser( + ProtoMessageResponseParser.newBuilder() + .setDefaultInstance(Empty.getDefaultInstance()) + .setDefaultTypeRegistry(typeRegistry) + .build()) + .build(); + + private final UnaryCallable createBudgetCallable; + private final UnaryCallable updateBudgetCallable; + private final UnaryCallable getBudgetCallable; + private final UnaryCallable listBudgetsCallable; + private final UnaryCallable + listBudgetsPagedCallable; + private final UnaryCallable deleteBudgetCallable; + + private final BackgroundResource backgroundResources; + private final HttpJsonStubCallableFactory callableFactory; + + public static final HttpJsonBudgetServiceStub create(BudgetServiceStubSettings settings) + throws IOException { + return new HttpJsonBudgetServiceStub(settings, ClientContext.create(settings)); + } + + public static final HttpJsonBudgetServiceStub create(ClientContext clientContext) + throws IOException { + return new HttpJsonBudgetServiceStub( + BudgetServiceStubSettings.newHttpJsonBuilder().build(), clientContext); + } + + public static final HttpJsonBudgetServiceStub create( + ClientContext clientContext, HttpJsonStubCallableFactory callableFactory) throws IOException { + return new HttpJsonBudgetServiceStub( + BudgetServiceStubSettings.newHttpJsonBuilder().build(), clientContext, callableFactory); + } + + /** + * Constructs an instance of HttpJsonBudgetServiceStub, 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 HttpJsonBudgetServiceStub( + BudgetServiceStubSettings settings, ClientContext clientContext) throws IOException { + this(settings, clientContext, new HttpJsonBudgetServiceCallableFactory()); + } + + /** + * Constructs an instance of HttpJsonBudgetServiceStub, 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 HttpJsonBudgetServiceStub( + BudgetServiceStubSettings settings, + ClientContext clientContext, + HttpJsonStubCallableFactory callableFactory) + throws IOException { + this.callableFactory = callableFactory; + + HttpJsonCallSettings createBudgetTransportSettings = + HttpJsonCallSettings.newBuilder() + .setMethodDescriptor(createBudgetMethodDescriptor) + .setTypeRegistry(typeRegistry) + .build(); + HttpJsonCallSettings updateBudgetTransportSettings = + HttpJsonCallSettings.newBuilder() + .setMethodDescriptor(updateBudgetMethodDescriptor) + .setTypeRegistry(typeRegistry) + .build(); + HttpJsonCallSettings getBudgetTransportSettings = + HttpJsonCallSettings.newBuilder() + .setMethodDescriptor(getBudgetMethodDescriptor) + .setTypeRegistry(typeRegistry) + .build(); + HttpJsonCallSettings listBudgetsTransportSettings = + HttpJsonCallSettings.newBuilder() + .setMethodDescriptor(listBudgetsMethodDescriptor) + .setTypeRegistry(typeRegistry) + .build(); + HttpJsonCallSettings deleteBudgetTransportSettings = + HttpJsonCallSettings.newBuilder() + .setMethodDescriptor(deleteBudgetMethodDescriptor) + .setTypeRegistry(typeRegistry) + .build(); + + this.createBudgetCallable = + callableFactory.createUnaryCallable( + createBudgetTransportSettings, settings.createBudgetSettings(), clientContext); + this.updateBudgetCallable = + callableFactory.createUnaryCallable( + updateBudgetTransportSettings, settings.updateBudgetSettings(), clientContext); + this.getBudgetCallable = + callableFactory.createUnaryCallable( + getBudgetTransportSettings, settings.getBudgetSettings(), clientContext); + this.listBudgetsCallable = + callableFactory.createUnaryCallable( + listBudgetsTransportSettings, settings.listBudgetsSettings(), clientContext); + this.listBudgetsPagedCallable = + callableFactory.createPagedCallable( + listBudgetsTransportSettings, settings.listBudgetsSettings(), clientContext); + this.deleteBudgetCallable = + callableFactory.createUnaryCallable( + deleteBudgetTransportSettings, settings.deleteBudgetSettings(), clientContext); + + this.backgroundResources = + new BackgroundResourceAggregation(clientContext.getBackgroundResources()); + } + + @InternalApi + public static List getMethodDescriptors() { + List methodDescriptors = new ArrayList<>(); + methodDescriptors.add(createBudgetMethodDescriptor); + methodDescriptors.add(updateBudgetMethodDescriptor); + methodDescriptors.add(getBudgetMethodDescriptor); + methodDescriptors.add(listBudgetsMethodDescriptor); + methodDescriptors.add(deleteBudgetMethodDescriptor); + return methodDescriptors; + } + + @Override + public UnaryCallable createBudgetCallable() { + return createBudgetCallable; + } + + @Override + public UnaryCallable updateBudgetCallable() { + return updateBudgetCallable; + } + + @Override + public UnaryCallable getBudgetCallable() { + return getBudgetCallable; + } + + @Override + public UnaryCallable listBudgetsCallable() { + return listBudgetsCallable; + } + + @Override + public UnaryCallable listBudgetsPagedCallable() { + return listBudgetsPagedCallable; + } + + @Override + public UnaryCallable deleteBudgetCallable() { + return deleteBudgetCallable; + } + + @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/google-cloud-billingbudgets/src/test/java/com/google/cloud/billing/budgets/v1/BudgetServiceClientHttpJsonTest.java b/google-cloud-billingbudgets/src/test/java/com/google/cloud/billing/budgets/v1/BudgetServiceClientHttpJsonTest.java new file mode 100644 index 00000000..470a0a45 --- /dev/null +++ b/google-cloud-billingbudgets/src/test/java/com/google/cloud/billing/budgets/v1/BudgetServiceClientHttpJsonTest.java @@ -0,0 +1,534 @@ +/* + * Copyright 2022 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.billing.budgets.v1; + +import static com.google.cloud.billing.budgets.v1.BudgetServiceClient.ListBudgetsPagedResponse; + +import com.google.api.gax.core.NoCredentialsProvider; +import com.google.api.gax.httpjson.GaxHttpJsonProperties; +import com.google.api.gax.httpjson.testing.MockHttpService; +import com.google.api.gax.rpc.ApiClientHeaderProvider; +import com.google.api.gax.rpc.ApiException; +import com.google.api.gax.rpc.ApiExceptionFactory; +import com.google.api.gax.rpc.InvalidArgumentException; +import com.google.api.gax.rpc.StatusCode; +import com.google.api.gax.rpc.testing.FakeStatusCode; +import com.google.cloud.billing.budgets.v1.stub.HttpJsonBudgetServiceStub; +import com.google.common.collect.Lists; +import com.google.protobuf.Empty; +import com.google.protobuf.FieldMask; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import javax.annotation.Generated; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +@Generated("by gapic-generator-java") +public class BudgetServiceClientHttpJsonTest { + private static MockHttpService mockService; + private static BudgetServiceClient client; + + @BeforeClass + public static void startStaticServer() throws IOException { + mockService = + new MockHttpService( + HttpJsonBudgetServiceStub.getMethodDescriptors(), + BudgetServiceSettings.getDefaultEndpoint()); + BudgetServiceSettings settings = + BudgetServiceSettings.newHttpJsonBuilder() + .setTransportChannelProvider( + BudgetServiceSettings.defaultHttpJsonTransportProviderBuilder() + .setHttpTransport(mockService) + .build()) + .setCredentialsProvider(NoCredentialsProvider.create()) + .build(); + client = BudgetServiceClient.create(settings); + } + + @AfterClass + public static void stopServer() { + client.close(); + } + + @Before + public void setUp() {} + + @After + public void tearDown() throws Exception { + mockService.reset(); + } + + @Test + public void createBudgetTest() throws Exception { + Budget expectedResponse = + Budget.newBuilder() + .setName(BudgetName.of("[BILLING_ACCOUNT]", "[BUDGET]").toString()) + .setDisplayName("displayName1714148973") + .setBudgetFilter(Filter.newBuilder().build()) + .setAmount(BudgetAmount.newBuilder().build()) + .addAllThresholdRules(new ArrayList()) + .setNotificationsRule(NotificationsRule.newBuilder().build()) + .setEtag("etag3123477") + .build(); + mockService.addResponse(expectedResponse); + + BillingAccountName parent = BillingAccountName.of("[BILLING_ACCOUNT]"); + Budget budget = Budget.newBuilder().build(); + + Budget actualResponse = client.createBudget(parent, budget); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockService.getRequestPaths(); + Assert.assertEquals(1, actualRequests.size()); + + String apiClientHeaderKey = + mockService + .getRequestHeaders() + .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey()) + .iterator() + .next(); + Assert.assertTrue( + GaxHttpJsonProperties.getDefaultApiClientHeaderPattern() + .matcher(apiClientHeaderKey) + .matches()); + } + + @Test + public void createBudgetExceptionTest() throws Exception { + ApiException exception = + ApiExceptionFactory.createException( + new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false); + mockService.addException(exception); + + try { + BillingAccountName parent = BillingAccountName.of("[BILLING_ACCOUNT]"); + Budget budget = Budget.newBuilder().build(); + client.createBudget(parent, budget); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } + + @Test + public void createBudgetTest2() throws Exception { + Budget expectedResponse = + Budget.newBuilder() + .setName(BudgetName.of("[BILLING_ACCOUNT]", "[BUDGET]").toString()) + .setDisplayName("displayName1714148973") + .setBudgetFilter(Filter.newBuilder().build()) + .setAmount(BudgetAmount.newBuilder().build()) + .addAllThresholdRules(new ArrayList()) + .setNotificationsRule(NotificationsRule.newBuilder().build()) + .setEtag("etag3123477") + .build(); + mockService.addResponse(expectedResponse); + + String parent = "billingAccounts/billingAccount-7950"; + Budget budget = Budget.newBuilder().build(); + + Budget actualResponse = client.createBudget(parent, budget); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockService.getRequestPaths(); + Assert.assertEquals(1, actualRequests.size()); + + String apiClientHeaderKey = + mockService + .getRequestHeaders() + .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey()) + .iterator() + .next(); + Assert.assertTrue( + GaxHttpJsonProperties.getDefaultApiClientHeaderPattern() + .matcher(apiClientHeaderKey) + .matches()); + } + + @Test + public void createBudgetExceptionTest2() throws Exception { + ApiException exception = + ApiExceptionFactory.createException( + new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false); + mockService.addException(exception); + + try { + String parent = "billingAccounts/billingAccount-7950"; + Budget budget = Budget.newBuilder().build(); + client.createBudget(parent, budget); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } + + @Test + public void updateBudgetTest() throws Exception { + Budget expectedResponse = + Budget.newBuilder() + .setName(BudgetName.of("[BILLING_ACCOUNT]", "[BUDGET]").toString()) + .setDisplayName("displayName1714148973") + .setBudgetFilter(Filter.newBuilder().build()) + .setAmount(BudgetAmount.newBuilder().build()) + .addAllThresholdRules(new ArrayList()) + .setNotificationsRule(NotificationsRule.newBuilder().build()) + .setEtag("etag3123477") + .build(); + mockService.addResponse(expectedResponse); + + Budget budget = + Budget.newBuilder() + .setName(BudgetName.of("[BILLING_ACCOUNT]", "[BUDGET]").toString()) + .setDisplayName("displayName1714148973") + .setBudgetFilter(Filter.newBuilder().build()) + .setAmount(BudgetAmount.newBuilder().build()) + .addAllThresholdRules(new ArrayList()) + .setNotificationsRule(NotificationsRule.newBuilder().build()) + .setEtag("etag3123477") + .build(); + FieldMask updateMask = FieldMask.newBuilder().build(); + + Budget actualResponse = client.updateBudget(budget, updateMask); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockService.getRequestPaths(); + Assert.assertEquals(1, actualRequests.size()); + + String apiClientHeaderKey = + mockService + .getRequestHeaders() + .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey()) + .iterator() + .next(); + Assert.assertTrue( + GaxHttpJsonProperties.getDefaultApiClientHeaderPattern() + .matcher(apiClientHeaderKey) + .matches()); + } + + @Test + public void updateBudgetExceptionTest() throws Exception { + ApiException exception = + ApiExceptionFactory.createException( + new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false); + mockService.addException(exception); + + try { + Budget budget = + Budget.newBuilder() + .setName(BudgetName.of("[BILLING_ACCOUNT]", "[BUDGET]").toString()) + .setDisplayName("displayName1714148973") + .setBudgetFilter(Filter.newBuilder().build()) + .setAmount(BudgetAmount.newBuilder().build()) + .addAllThresholdRules(new ArrayList()) + .setNotificationsRule(NotificationsRule.newBuilder().build()) + .setEtag("etag3123477") + .build(); + FieldMask updateMask = FieldMask.newBuilder().build(); + client.updateBudget(budget, updateMask); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } + + @Test + public void getBudgetTest() throws Exception { + Budget expectedResponse = + Budget.newBuilder() + .setName(BudgetName.of("[BILLING_ACCOUNT]", "[BUDGET]").toString()) + .setDisplayName("displayName1714148973") + .setBudgetFilter(Filter.newBuilder().build()) + .setAmount(BudgetAmount.newBuilder().build()) + .addAllThresholdRules(new ArrayList()) + .setNotificationsRule(NotificationsRule.newBuilder().build()) + .setEtag("etag3123477") + .build(); + mockService.addResponse(expectedResponse); + + BudgetName name = BudgetName.of("[BILLING_ACCOUNT]", "[BUDGET]"); + + Budget actualResponse = client.getBudget(name); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockService.getRequestPaths(); + Assert.assertEquals(1, actualRequests.size()); + + String apiClientHeaderKey = + mockService + .getRequestHeaders() + .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey()) + .iterator() + .next(); + Assert.assertTrue( + GaxHttpJsonProperties.getDefaultApiClientHeaderPattern() + .matcher(apiClientHeaderKey) + .matches()); + } + + @Test + public void getBudgetExceptionTest() throws Exception { + ApiException exception = + ApiExceptionFactory.createException( + new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false); + mockService.addException(exception); + + try { + BudgetName name = BudgetName.of("[BILLING_ACCOUNT]", "[BUDGET]"); + client.getBudget(name); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } + + @Test + public void getBudgetTest2() throws Exception { + Budget expectedResponse = + Budget.newBuilder() + .setName(BudgetName.of("[BILLING_ACCOUNT]", "[BUDGET]").toString()) + .setDisplayName("displayName1714148973") + .setBudgetFilter(Filter.newBuilder().build()) + .setAmount(BudgetAmount.newBuilder().build()) + .addAllThresholdRules(new ArrayList()) + .setNotificationsRule(NotificationsRule.newBuilder().build()) + .setEtag("etag3123477") + .build(); + mockService.addResponse(expectedResponse); + + String name = "billingAccounts/billingAccount-7221/budgets/budget-7221"; + + Budget actualResponse = client.getBudget(name); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockService.getRequestPaths(); + Assert.assertEquals(1, actualRequests.size()); + + String apiClientHeaderKey = + mockService + .getRequestHeaders() + .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey()) + .iterator() + .next(); + Assert.assertTrue( + GaxHttpJsonProperties.getDefaultApiClientHeaderPattern() + .matcher(apiClientHeaderKey) + .matches()); + } + + @Test + public void getBudgetExceptionTest2() throws Exception { + ApiException exception = + ApiExceptionFactory.createException( + new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false); + mockService.addException(exception); + + try { + String name = "billingAccounts/billingAccount-7221/budgets/budget-7221"; + client.getBudget(name); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } + + @Test + public void listBudgetsTest() throws Exception { + Budget responsesElement = Budget.newBuilder().build(); + ListBudgetsResponse expectedResponse = + ListBudgetsResponse.newBuilder() + .setNextPageToken("") + .addAllBudgets(Arrays.asList(responsesElement)) + .build(); + mockService.addResponse(expectedResponse); + + BillingAccountName parent = BillingAccountName.of("[BILLING_ACCOUNT]"); + + ListBudgetsPagedResponse pagedListResponse = client.listBudgets(parent); + + List resources = Lists.newArrayList(pagedListResponse.iterateAll()); + + Assert.assertEquals(1, resources.size()); + Assert.assertEquals(expectedResponse.getBudgetsList().get(0), resources.get(0)); + + List actualRequests = mockService.getRequestPaths(); + Assert.assertEquals(1, actualRequests.size()); + + String apiClientHeaderKey = + mockService + .getRequestHeaders() + .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey()) + .iterator() + .next(); + Assert.assertTrue( + GaxHttpJsonProperties.getDefaultApiClientHeaderPattern() + .matcher(apiClientHeaderKey) + .matches()); + } + + @Test + public void listBudgetsExceptionTest() throws Exception { + ApiException exception = + ApiExceptionFactory.createException( + new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false); + mockService.addException(exception); + + try { + BillingAccountName parent = BillingAccountName.of("[BILLING_ACCOUNT]"); + client.listBudgets(parent); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } + + @Test + public void listBudgetsTest2() throws Exception { + Budget responsesElement = Budget.newBuilder().build(); + ListBudgetsResponse expectedResponse = + ListBudgetsResponse.newBuilder() + .setNextPageToken("") + .addAllBudgets(Arrays.asList(responsesElement)) + .build(); + mockService.addResponse(expectedResponse); + + String parent = "billingAccounts/billingAccount-7950"; + + ListBudgetsPagedResponse pagedListResponse = client.listBudgets(parent); + + List resources = Lists.newArrayList(pagedListResponse.iterateAll()); + + Assert.assertEquals(1, resources.size()); + Assert.assertEquals(expectedResponse.getBudgetsList().get(0), resources.get(0)); + + List actualRequests = mockService.getRequestPaths(); + Assert.assertEquals(1, actualRequests.size()); + + String apiClientHeaderKey = + mockService + .getRequestHeaders() + .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey()) + .iterator() + .next(); + Assert.assertTrue( + GaxHttpJsonProperties.getDefaultApiClientHeaderPattern() + .matcher(apiClientHeaderKey) + .matches()); + } + + @Test + public void listBudgetsExceptionTest2() throws Exception { + ApiException exception = + ApiExceptionFactory.createException( + new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false); + mockService.addException(exception); + + try { + String parent = "billingAccounts/billingAccount-7950"; + client.listBudgets(parent); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } + + @Test + public void deleteBudgetTest() throws Exception { + Empty expectedResponse = Empty.newBuilder().build(); + mockService.addResponse(expectedResponse); + + BudgetName name = BudgetName.of("[BILLING_ACCOUNT]", "[BUDGET]"); + + client.deleteBudget(name); + + List actualRequests = mockService.getRequestPaths(); + Assert.assertEquals(1, actualRequests.size()); + + String apiClientHeaderKey = + mockService + .getRequestHeaders() + .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey()) + .iterator() + .next(); + Assert.assertTrue( + GaxHttpJsonProperties.getDefaultApiClientHeaderPattern() + .matcher(apiClientHeaderKey) + .matches()); + } + + @Test + public void deleteBudgetExceptionTest() throws Exception { + ApiException exception = + ApiExceptionFactory.createException( + new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false); + mockService.addException(exception); + + try { + BudgetName name = BudgetName.of("[BILLING_ACCOUNT]", "[BUDGET]"); + client.deleteBudget(name); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } + + @Test + public void deleteBudgetTest2() throws Exception { + Empty expectedResponse = Empty.newBuilder().build(); + mockService.addResponse(expectedResponse); + + String name = "billingAccounts/billingAccount-7221/budgets/budget-7221"; + + client.deleteBudget(name); + + List actualRequests = mockService.getRequestPaths(); + Assert.assertEquals(1, actualRequests.size()); + + String apiClientHeaderKey = + mockService + .getRequestHeaders() + .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey()) + .iterator() + .next(); + Assert.assertTrue( + GaxHttpJsonProperties.getDefaultApiClientHeaderPattern() + .matcher(apiClientHeaderKey) + .matches()); + } + + @Test + public void deleteBudgetExceptionTest2() throws Exception { + ApiException exception = + ApiExceptionFactory.createException( + new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false); + mockService.addException(exception); + + try { + String name = "billingAccounts/billingAccount-7221/budgets/budget-7221"; + client.deleteBudget(name); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } +}