diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c532d218..6a39051b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [2.2.0](https://www.github.com/googleapis/gax-java/compare/v2.1.0...v2.2.0) (2021-08-13) + + +### Features + +* Add AIP-151 LRO OperationsClient to gax-httpjson ([#1458](https://www.github.com/googleapis/gax-java/issues/1458)) ([314acb6](https://www.github.com/googleapis/gax-java/commit/314acb6a5c335732e8406bec86f6c37296ebf3f3)) + ## [2.1.0](https://www.github.com/googleapis/gax-java/compare/v2.0.0...v2.1.0) (2021-08-11) diff --git a/README.md b/README.md index bef0cf598..928259581 100644 --- a/README.md +++ b/README.md @@ -29,27 +29,27 @@ If you are using Maven, add this to your pom.xml file com.google.api gax - 2.1.0 + 2.2.0 com.google.api gax-grpc - 2.1.0 + 2.2.0 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.api:gax:2.1.0', - 'com.google.api:gax-grpc:2.1.0' +compile 'com.google.api:gax:2.2.0', + 'com.google.api:gax-grpc:2.2.0' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.api" % "gax" % "2.1.0" -libraryDependencies += "com.google.api" % "gax-grpc" % "2.1.0" +libraryDependencies += "com.google.api" % "gax" % "2.2.0" +libraryDependencies += "com.google.api" % "gax-grpc" % "2.2.0" ``` [//]: # ({x-version-update-end}) diff --git a/benchmark/build.gradle b/benchmark/build.gradle index d1786c089..6df5bf3ce 100644 --- a/benchmark/build.gradle +++ b/benchmark/build.gradle @@ -1,4 +1,4 @@ -project.version = "0.71.0" // {x-version-update:benchmark:current} +project.version = "0.72.0" // {x-version-update:benchmark:current} buildscript { repositories { diff --git a/build.gradle b/build.gradle index 1990783e0..1ea0f2cdb 100644 --- a/build.gradle +++ b/build.gradle @@ -24,7 +24,7 @@ apply plugin: 'com.github.sherter.google-java-format' apply plugin: 'io.codearte.nexus-staging' // TODO: Populate this from dependencies.properties version property (for proper Gradle-Bazel sync) -project.version = "2.1.0" // {x-version-update:gax:current} +project.version = "2.2.0" // {x-version-update:gax:current} ext { // Project names not used for release diff --git a/dependencies.properties b/dependencies.properties index fc09befc0..605cfd362 100644 --- a/dependencies.properties +++ b/dependencies.properties @@ -8,16 +8,16 @@ # Versions of oneself # {x-version-update-start:gax:current} -version.gax=2.1.0 +version.gax=2.2.0 # {x-version-update-end} # {x-version-update-start:gax:current} -version.gax_grpc=2.1.0 +version.gax_grpc=2.2.0 # {x-version-update-end} # {x-version-update-start:gax:current} -version.gax_bom=2.1.0 +version.gax_bom=2.2.0 # {x-version-update-end} # {x-version-update-start:gax-httpjson:current} -version.gax_httpjson=0.86.0 +version.gax_httpjson=0.87.0 # {x-version-update-end} # Versions for dependencies which actual artifacts differ between Bazel and Gradle. diff --git a/gax-bom/build.gradle b/gax-bom/build.gradle index 15cc53a6e..94c6269b0 100644 --- a/gax-bom/build.gradle +++ b/gax-bom/build.gradle @@ -12,7 +12,7 @@ buildscript { archivesBaseName = "gax-bom" -project.version = "2.1.0" // {x-version-update:gax-bom:current} +project.version = "2.2.0" // {x-version-update:gax-bom:current} ext { mavenJavaDir = "$project.buildDir/publications/mavenJava" diff --git a/gax-bom/pom.xml b/gax-bom/pom.xml index 7578d0588..981519dc2 100644 --- a/gax-bom/pom.xml +++ b/gax-bom/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.api gax-bom - 2.1.0 + 2.2.0 pom GAX (Google Api eXtensions) for Java Google Api eXtensions for Java @@ -33,34 +33,34 @@ com.google.api gax - 2.1.0 + 2.2.0 com.google.api gax - 2.1.0 + 2.2.0 testlib com.google.api gax-grpc - 2.1.0 + 2.2.0 com.google.api gax-grpc - 2.1.0 + 2.2.0 testlib com.google.api gax-httpjson - 0.86.0 + 0.87.0 com.google.api gax-httpjson - 0.86.0 + 0.87.0 testlib diff --git a/gax-grpc/build.gradle b/gax-grpc/build.gradle index 8dd9c2701..5f5b0f83f 100644 --- a/gax-grpc/build.gradle +++ b/gax-grpc/build.gradle @@ -1,7 +1,7 @@ archivesBaseName = "gax-grpc" // TODO: Populate this from dependencies.properties version property (for proper Gradle-Bazel sync) -project.version = "2.1.0" // {x-version-update:gax-grpc:current} +project.version = "2.2.0" // {x-version-update:gax-grpc:current} dependencies { compile project(':gax'), diff --git a/gax-httpjson/BUILD.bazel b/gax-httpjson/BUILD.bazel index f2e40f76a..0ddf20181 100644 --- a/gax-httpjson/BUILD.bazel +++ b/gax-httpjson/BUILD.bazel @@ -20,6 +20,7 @@ _COMPILE_DEPS = [ "@com_google_auto_value_auto_value_annotations//jar", "@javax_annotation_javax_annotation_api//jar", "@com_google_http_client_google_http_client_gson//jar", + "@com_google_api_grpc_proto_google_common_protos//jar", "@com_google_protobuf//:protobuf_java", "@com_google_protobuf_java_util//jar", "//gax:gax", diff --git a/gax-httpjson/build.gradle b/gax-httpjson/build.gradle index 7b1d86b27..8a73bbf9f 100644 --- a/gax-httpjson/build.gradle +++ b/gax-httpjson/build.gradle @@ -1,7 +1,7 @@ archivesBaseName = "gax-httpjson" // TODO: Populate this from dependencies.properties version property (for proper Gradle-Bazel sync) -project.version = "0.86.0" // {x-version-update:gax-httpjson:current} +project.version = "0.87.0" // {x-version-update:gax-httpjson:current} dependencies { compile project(':gax'), @@ -15,6 +15,7 @@ dependencies { libraries['maven.com_google_http_client_google_http_client_gson'], libraries['maven.com_google_auth_google_auth_library_oauth2_http'], libraries['maven.com_google_auth_google_auth_library_credentials'], + libraries['maven.com_google_api_grpc_proto_google_common_protos'] libraries['maven.com_google_api_api_common'] compileOnly libraries['maven.com_google_auto_value_auto_value'] diff --git a/gax-httpjson/src/main/java/com/google/api/gax/httpjson/ApiMethodDescriptor.java b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/ApiMethodDescriptor.java index a31110fd0..665aea66f 100644 --- a/gax-httpjson/src/main/java/com/google/api/gax/httpjson/ApiMethodDescriptor.java +++ b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/ApiMethodDescriptor.java @@ -49,6 +49,12 @@ public abstract class ApiMethodDescriptor { @Nullable public abstract String getHttpMethod(); + @Nullable + public abstract OperationSnapshotFactory getOperationSnapshotFactory(); + + @Nullable + public abstract PollingRequestFactory getPollingRequestFactory(); + public static Builder newBuilder() { return new AutoValue_ApiMethodDescriptor.Builder(); } @@ -66,6 +72,12 @@ public abstract Builder setResponseParser( public abstract Builder setHttpMethod(String httpMethod); + public abstract Builder setOperationSnapshotFactory( + OperationSnapshotFactory operationSnapshotFactory); + + public abstract Builder setPollingRequestFactory( + PollingRequestFactory pollingRequestFactory); + public abstract ApiMethodDescriptor build(); } } diff --git a/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpJsonCallableFactory.java b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpJsonCallableFactory.java index 574780cac..66ff47cab 100644 --- a/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpJsonCallableFactory.java +++ b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpJsonCallableFactory.java @@ -86,10 +86,8 @@ public static UnaryCallable createBas HttpJsonCallSettings httpJsonCallSettings, UnaryCallSettings callSettings, ClientContext clientContext) { - UnaryCallable callable = - new HttpJsonDirectCallable<>(httpJsonCallSettings.getMethodDescriptor()); + UnaryCallable callable = createDirectUnaryCallable(httpJsonCallSettings); callable = new HttpJsonExceptionCallable<>(callable, callSettings.getRetryableCodes()); - callable = Callables.retrying(callable, callSettings, clientContext); return callable; diff --git a/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpJsonLongRunningClient.java b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpJsonLongRunningClient.java new file mode 100644 index 000000000..7e1601434 --- /dev/null +++ b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpJsonLongRunningClient.java @@ -0,0 +1,92 @@ +/* + * Copyright 2021 Google LLC + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google LLC nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.google.api.gax.httpjson; + +import com.google.api.core.ApiFunction; +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.api.gax.longrunning.OperationSnapshot; +import com.google.api.gax.rpc.LongRunningClient; +import com.google.api.gax.rpc.TranslatingUnaryCallable; +import com.google.api.gax.rpc.UnaryCallable; + +/** + * Implementation of LongRunningClient based on REST transport. + * + *

Public for technical reasons. For internal use only. + */ +@BetaApi("The surface for long-running operations is not stable yet and may change in the future.") +@InternalApi +public class HttpJsonLongRunningClient implements LongRunningClient { + + private final UnaryCallable operationCallable; + private final OperationSnapshotFactory operationSnapshotFactory; + private final PollingRequestFactory pollingRequestFactory; + + public HttpJsonLongRunningClient( + UnaryCallable operationCallable, + OperationSnapshotFactory operationSnapshotFactory, + PollingRequestFactory pollingRequestFactory) { + this.operationCallable = operationCallable; + this.operationSnapshotFactory = operationSnapshotFactory; + this.pollingRequestFactory = pollingRequestFactory; + } + + /** {@inheritDoc} */ + @Override + public UnaryCallable getOperationCallable() { + return TranslatingUnaryCallable.create( + operationCallable, + new ApiFunction() { + @Override + public RequestT apply(String id) { + return pollingRequestFactory.create(id); + } + }, + new ApiFunction() { + @Override + public OperationSnapshot apply(OperationT operation) { + return operationSnapshotFactory.create(null, operation); + } + }); + } + + /** {@inheritDoc} */ + @Override + public UnaryCallable cancelOperationCallable() { + return null; + } + + /** {@inheritDoc} */ + @Override + public UnaryCallable deleteOperationCallable() { + return null; + } +} diff --git a/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpJsonOperationSnapshot.java b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpJsonOperationSnapshot.java new file mode 100644 index 000000000..ff49b45eb --- /dev/null +++ b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpJsonOperationSnapshot.java @@ -0,0 +1,151 @@ +/* + * Copyright 2021 Google LLC + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google LLC nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.google.api.gax.httpjson; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.api.gax.longrunning.OperationSnapshot; +import com.google.api.gax.rpc.StatusCode; + +/** + * Implementation of OperationSnapshot based on REST transport. + * + *

Public for technical reasons. For internal use only. + */ +@BetaApi("The surface for long-running operations is not stable yet and may change in the future.") +@InternalApi +public class HttpJsonOperationSnapshot implements OperationSnapshot { + + private final String name; + private final Object metadata; + private final boolean done; + private final Object response; + private final StatusCode errorCode; + private final String errorMessage; + + public HttpJsonOperationSnapshot( + String name, + Object metadata, + boolean done, + Object response, + int errorCode, + String errorMessage) { + this.name = name; + this.metadata = metadata; + this.done = done; + this.response = done ? response : null; + if (done && errorCode != 0) { + this.errorCode = HttpJsonStatusCode.of(errorCode, errorMessage); + this.errorMessage = errorMessage; + } else { + this.errorCode = null; + this.errorMessage = null; + } + } + + /** {@inheritDoc} */ + @Override + public String getName() { + return this.name; + } + + /** {@inheritDoc} */ + @Override + public Object getMetadata() { + return this.metadata; + } + + /** {@inheritDoc} */ + @Override + public boolean isDone() { + return done; + } + + /** {@inheritDoc} */ + @Override + public Object getResponse() { + return this.response; + } + + /** {@inheritDoc} */ + @Override + public StatusCode getErrorCode() { + return this.errorCode; + } + + /** {@inheritDoc} */ + @Override + public String getErrorMessage() { + return this.errorMessage; + } + + public static Builder newBuilder() { + return new HttpJsonOperationSnapshot.Builder(); + } + + public static class Builder { + private String name; + private Object metadata; + private boolean done; + private Object response; + private int errorCode; + private String errorMessage; + + public Builder setName(String name) { + this.name = name; + return this; + } + + public Builder setMetadata(Object metadata) { + this.metadata = metadata; + return this; + } + + public Builder setDone(boolean done) { + this.done = done; + return this; + } + + public Builder setResponse(Object response) { + this.response = response; + return this; + } + + public Builder setError(int errorCode, String errorMessage) { + this.errorCode = errorCode; + this.errorMessage = errorMessage; + return this; + } + + public HttpJsonOperationSnapshot build() { + return new HttpJsonOperationSnapshot(name, metadata, done, response, errorCode, errorMessage); + } + } +} diff --git a/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpJsonOperationSnapshotCallable.java b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpJsonOperationSnapshotCallable.java new file mode 100644 index 000000000..30a278011 --- /dev/null +++ b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpJsonOperationSnapshotCallable.java @@ -0,0 +1,77 @@ +/* + * Copyright 2021 Google LLC + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google LLC nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.google.api.gax.httpjson; + +import static com.google.common.util.concurrent.MoreExecutors.directExecutor; + +import com.google.api.core.ApiFunction; +import com.google.api.core.ApiFuture; +import com.google.api.core.ApiFutures; +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.api.gax.longrunning.OperationSnapshot; +import com.google.api.gax.rpc.ApiCallContext; +import com.google.api.gax.rpc.UnaryCallable; + +/** + * A {@code UnaryCallable} that wraps a UnaryCallable returning an Operation and returns an + * OperationSnapshot instead. + * + *

Public for technical reasons. For internal use only. + */ +@BetaApi("The surface for long-running operations is not stable yet and may change in the future.") +@InternalApi +public class HttpJsonOperationSnapshotCallable + extends UnaryCallable { + + private final UnaryCallable innerCallable; + private final OperationSnapshotFactory operationSnapshotFactory; + + public HttpJsonOperationSnapshotCallable( + UnaryCallable innerCallable, + OperationSnapshotFactory operationSnapshotFactory) { + this.innerCallable = innerCallable; + this.operationSnapshotFactory = operationSnapshotFactory; + } + + /** {@inheritDoc} */ + @Override + public ApiFuture futureCall(final RequestT request, ApiCallContext context) { + return ApiFutures.transform( + innerCallable.futureCall(request, context), + new ApiFunction() { + @Override + public OperationSnapshot apply(OperationT operation) { + return operationSnapshotFactory.create(request, operation); + } + }, + directExecutor()); + } +} diff --git a/gax-httpjson/src/main/java/com/google/api/gax/httpjson/OperationSnapshotFactory.java b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/OperationSnapshotFactory.java new file mode 100644 index 000000000..a62c9e4a9 --- /dev/null +++ b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/OperationSnapshotFactory.java @@ -0,0 +1,48 @@ +/* + * Copyright 2021 Google LLC + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google LLC nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.google.api.gax.httpjson; + +import com.google.api.core.BetaApi; +import com.google.api.gax.longrunning.OperationSnapshot; + +/** + * A factory which creates an {@link OperationSnapshot} from an initial request message (the one + * which started a long running operation) and an operation response (which may be either initial + * request response or the polling request response). + * + *

Public for technical reasons. For internal use only. + * + * @param initial request message type + * @param initial or polling response type + */ +@BetaApi("The surface for long-running operations is not stable yet and may change in the future.") +public interface OperationSnapshotFactory { + OperationSnapshot create(RequestT request, OperationT response); +} diff --git a/gax-httpjson/src/main/java/com/google/api/gax/httpjson/PollingRequestFactory.java b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/PollingRequestFactory.java new file mode 100644 index 000000000..21d24a3aa --- /dev/null +++ b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/PollingRequestFactory.java @@ -0,0 +1,48 @@ +/* + * Copyright 2021 Google LLC + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google LLC nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.google.api.gax.httpjson; + +import com.google.api.core.BetaApi; + +/** + * A factory which creates a subsequent polling request from a compund operation id. + * + * @param polling request type + */ +@BetaApi("The surface for long-running operations is not stable yet and may change in the future.") +public interface PollingRequestFactory { + /** + * Creates a polling request message from a {@code compoundOperationId}. + * + * @param compoundOperationId the compound operation ID, consisting of an operation name and + * potentially any other relevant information delimited by a ':' * character + */ + RequestT create(String compoundOperationId); +} diff --git a/gax-httpjson/src/main/java/com/google/api/gax/httpjson/ProtoOperationTransformers.java b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/ProtoOperationTransformers.java new file mode 100644 index 000000000..d2b0cfcc4 --- /dev/null +++ b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/ProtoOperationTransformers.java @@ -0,0 +1,73 @@ +/* + * Copyright 2020 Google LLC + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google LLC nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.google.api.gax.httpjson; + +import com.google.api.core.ApiFunction; +import com.google.api.core.BetaApi; +import com.google.api.gax.longrunning.OperationSnapshot; +import com.google.protobuf.Message; + +/** Public for technical reasons; intended for use by generated code. */ +@BetaApi("The surface for use by generated code is not stable yet and may change in the future.") +public class ProtoOperationTransformers { + private ProtoOperationTransformers() {} + + public static class ResponseTransformer + implements ApiFunction { + + private ResponseTransformer() {} + + @Override + public ResponseT apply(OperationSnapshot operationSnapshot) { + return (ResponseT) operationSnapshot.getResponse(); + } + + public static ResponseTransformer create( + Class packedClass) { + return new ResponseTransformer<>(); + } + } + + public static class MetadataTransformer + implements ApiFunction { + + private MetadataTransformer() {} + + @Override + public ResponseT apply(OperationSnapshot operationSnapshot) { + return (ResponseT) operationSnapshot.getMetadata(); + } + + public static MetadataTransformer create( + Class packedClass) { + return new MetadataTransformer<>(); + } + } +} diff --git a/gax-httpjson/src/main/java/com/google/api/gax/httpjson/longrunning/OperationsClient.java b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/longrunning/OperationsClient.java new file mode 100644 index 000000000..929d9d64c --- /dev/null +++ b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/longrunning/OperationsClient.java @@ -0,0 +1,659 @@ +/* + * Copyright 2021 Google LLC + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google LLC nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.google.api.gax.httpjson.longrunning; + +import com.google.api.core.ApiFunction; +import com.google.api.core.ApiFuture; +import com.google.api.core.ApiFutures; +import com.google.api.core.BetaApi; +import com.google.api.gax.core.BackgroundResource; +import com.google.api.gax.httpjson.longrunning.stub.OperationsStub; +import com.google.api.gax.httpjson.longrunning.stub.OperationsStubSettings; +import com.google.api.gax.paging.AbstractFixedSizeCollection; +import com.google.api.gax.paging.AbstractPage; +import com.google.api.gax.paging.AbstractPagedListResponse; +import com.google.api.gax.rpc.PageContext; +import com.google.api.gax.rpc.UnaryCallable; +import com.google.common.util.concurrent.MoreExecutors; +import com.google.longrunning.CancelOperationRequest; +import com.google.longrunning.DeleteOperationRequest; +import com.google.longrunning.GetOperationRequest; +import com.google.longrunning.ListOperationsRequest; +import com.google.longrunning.ListOperationsResponse; +import com.google.longrunning.Operation; +import com.google.protobuf.Empty; +import java.io.IOException; +import java.util.List; +import java.util.concurrent.TimeUnit; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * Service Description: Manages long-running operations with an API service. + * + *

When an API method normally takes long time to complete, it can be designed to return + * [Operation][google.longrunning.Operation] to the client, and the client can use this interface to + * receive the real response asynchronously by polling the operation resource, or pass the operation + * resource to another API (such as Google Cloud Pub/Sub API) to receive the response. Any API + * service that returns long-running operations should implement the `Operations` interface so + * developers can have a consistent client experience. + * + *

This class provides the ability to make remote calls to the backing service through method + * calls that map to API methods. Sample code to get started: + * + *

{@code
+ * try (OperationsClient operationsClient = OperationsClient.create()) {
+ *   String name = "name3373707";
+ *   Operation response = operationsClient.getOperation(name);
+ * }
+ * }
+ * + *

Note: close() needs to be called on the OperationsClient object to clean up resources such as + * threads. In the example above, try-with-resources is used, which automatically calls close(). + * + *

The surface of this class includes several types of Java methods for each of the API's + * methods: + * + *

    + *
  1. A "flattened" method. With this type of method, the fields of the request type have been + * converted into function parameters. It may be the case that not all fields are available as + * parameters, and not every API method will have a flattened method entry point. + *
  2. A "request object" method. This type of method only takes one parameter, a request object, + * which must be constructed before the call. Not every API method will have a request object + * method. + *
  3. A "callable" method. This type of method takes no parameters and returns an immutable API + * callable object, which can be used to initiate calls to the service. + *
+ * + *

See the individual methods for example code. + * + *

Many parameters require resource names to be formatted in a particular way. To assist with + * these names, this class includes a format method for each type of name, and additionally a parse + * method to extract the individual identifiers contained within names that are returned. + * + *

This class can be customized by passing in a custom instance of OperationsSettings to + * create(). For example: + * + *

To customize credentials: + * + *

{@code
+ * OperationsSettings operationsSettings =
+ *     OperationsSettings.newBuilder()
+ *         .setCredentialsProvider(FixedCredentialsProvider.create(myCredentials))
+ *         .build();
+ * OperationsClient operationsClient = OperationsClient.create(operationsSettings);
+ * }
+ * + *

To customize the endpoint: + * + *

{@code
+ * OperationsSettings operationsSettings =
+ *     OperationsSettings.newBuilder().setEndpoint(myEndpoint).build();
+ * OperationsClient operationsClient = OperationsClient.create(operationsSettings);
+ * }
+ * + *

Please refer to the GitHub repository's samples for more quickstart code snippets. + */ +@Generated("by gapic-generator-java") +@BetaApi +public class OperationsClient implements BackgroundResource { + private final OperationsSettings settings; + private final OperationsStub stub; + + /** Constructs an instance of OperationsClient with default settings. */ + public static final OperationsClient create() throws IOException { + return create(OperationsSettings.newBuilder().build()); + } + + /** + * Constructs an instance of OperationsClient, using the given settings. The channels are created + * based on the settings passed in, or defaults for any settings that are not set. + */ + public static final OperationsClient create(OperationsSettings settings) throws IOException { + return new OperationsClient(settings); + } + + /** + * Constructs an instance of OperationsClient, using the given stub for making calls. This is for + * advanced usage - prefer using create(OperationsSettings). + */ + @BetaApi("A restructuring of stub classes is planned, so this may break in the future") + public static final OperationsClient create(OperationsStub stub) { + return new OperationsClient(stub); + } + + /** + * Constructs an instance of OperationsClient, using the given stub for making calls. This is for + * advanced usage - prefer using create(OperationsSettings). + */ + @BetaApi("A restructuring of stub classes is planned, so this may break in the future") + public static final OperationsClient create(BackgroundResource stub) { + return new OperationsClient((OperationsStub) stub); + } + + /** + * Constructs an instance of OperationsClient, 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 OperationsClient(OperationsSettings settings) throws IOException { + this.settings = settings; + this.stub = ((OperationsStubSettings) settings.getStubSettings()).createStub(); + } + + @BetaApi("A restructuring of stub classes is planned, so this may break in the future") + protected OperationsClient(OperationsStub stub) { + this.settings = null; + this.stub = stub; + } + + public final OperationsSettings getSettings() { + return settings; + } + + @BetaApi("A restructuring of stub classes is planned, so this may break in the future") + public OperationsStub getStub() { + return stub; + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Lists operations that match the specified filter in the request. If the server doesn't support + * this method, it returns `UNIMPLEMENTED`. + * + *

NOTE: the `name` binding allows API services to override the binding to use different + * resource name schemes, such as `users/*/operations`. To override the binding, API services + * can add a binding such as `"/v1/{name=users/*}/operations"` to their service configuration. + * For backwards compatibility, the default name includes the operations collection id, however + * overriding users must ensure the name binding is the parent resource, without the operations + * collection id. + * + *

Sample code: + * + *

{@code
+   * try (OperationsClient operationsClient = OperationsClient.create()) {
+   *   String name = "name3373707";
+   *   String filter = "filter-1274492040";
+   *   for (Operation element : operationsClient.listOperations(name, filter).iterateAll()) {
+   *     // doThingsWith(element);
+   *   }
+   * }
+   * }
+ * + * @param name The name of the operation's parent resource. + * @param filter The standard list filter. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final ListOperationsPagedResponse listOperations(String name, String filter) { + ListOperationsRequest request = + ListOperationsRequest.newBuilder().setName(name).setFilter(filter).build(); + return listOperations(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Lists operations that match the specified filter in the request. If the server doesn't support + * this method, it returns `UNIMPLEMENTED`. + * + *

NOTE: the `name` binding allows API services to override the binding to use different + * resource name schemes, such as `users/*/operations`. To override the binding, API services + * can add a binding such as `"/v1/{name=users/*}/operations"` to their service configuration. + * For backwards compatibility, the default name includes the operations collection id, however + * overriding users must ensure the name binding is the parent resource, without the operations + * collection id. + * + *

Sample code: + * + *

{@code
+   * try (OperationsClient operationsClient = OperationsClient.create()) {
+   *   ListOperationsRequest request =
+   *       ListOperationsRequest.newBuilder()
+   *           .setName("name3373707")
+   *           .setFilter("filter-1274492040")
+   *           .setPageSize(883849137)
+   *           .setPageToken("pageToken873572522")
+   *           .build();
+   *   for (Operation element : operationsClient.listOperations(request).iterateAll()) {
+   *     // doThingsWith(element);
+   *   }
+   * }
+   * }
+ * + * @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 ListOperationsPagedResponse listOperations(ListOperationsRequest request) { + return listOperationsPagedCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Lists operations that match the specified filter in the request. If the server doesn't support + * this method, it returns `UNIMPLEMENTED`. + * + *

NOTE: the `name` binding allows API services to override the binding to use different + * resource name schemes, such as `users/*/operations`. To override the binding, API services + * can add a binding such as `"/v1/{name=users/*}/operations"` to their service configuration. + * For backwards compatibility, the default name includes the operations collection id, however + * overriding users must ensure the name binding is the parent resource, without the operations + * collection id. + * + *

Sample code: + * + *

{@code
+   * try (OperationsClient operationsClient = OperationsClient.create()) {
+   *   ListOperationsRequest request =
+   *       ListOperationsRequest.newBuilder()
+   *           .setName("name3373707")
+   *           .setFilter("filter-1274492040")
+   *           .setPageSize(883849137)
+   *           .setPageToken("pageToken873572522")
+   *           .build();
+   *   ApiFuture future =
+   *       operationsClient.listOperationsPagedCallable().futureCall(request);
+   *   // Do something.
+   *   for (Operation element : future.get().iterateAll()) {
+   *     // doThingsWith(element);
+   *   }
+   * }
+   * }
+ */ + public final UnaryCallable + listOperationsPagedCallable() { + return stub.listOperationsPagedCallable(); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Lists operations that match the specified filter in the request. If the server doesn't support + * this method, it returns `UNIMPLEMENTED`. + * + *

NOTE: the `name` binding allows API services to override the binding to use different + * resource name schemes, such as `users/*/operations`. To override the binding, API services + * can add a binding such as `"/v1/{name=users/*}/operations"` to their service configuration. + * For backwards compatibility, the default name includes the operations collection id, however + * overriding users must ensure the name binding is the parent resource, without the operations + * collection id. + * + *

Sample code: + * + *

{@code
+   * try (OperationsClient operationsClient = OperationsClient.create()) {
+   *   ListOperationsRequest request =
+   *       ListOperationsRequest.newBuilder()
+   *           .setName("name3373707")
+   *           .setFilter("filter-1274492040")
+   *           .setPageSize(883849137)
+   *           .setPageToken("pageToken873572522")
+   *           .build();
+   *   while (true) {
+   *     ListOperationsResponse response = operationsClient.listOperationsCallable().call(request);
+   *     for (Operation element : response.getResponsesList()) {
+   *       // doThingsWith(element);
+   *     }
+   *     String nextPageToken = response.getNextPageToken();
+   *     if (!Strings.isNullOrEmpty(nextPageToken)) {
+   *       request = request.toBuilder().setPageToken(nextPageToken).build();
+   *     } else {
+   *       break;
+   *     }
+   *   }
+   * }
+   * }
+ */ + public final UnaryCallable + listOperationsCallable() { + return stub.listOperationsCallable(); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Gets the latest state of a long-running operation. Clients can use this method to poll the + * operation result at intervals as recommended by the API service. + * + *

Sample code: + * + *

{@code
+   * try (OperationsClient operationsClient = OperationsClient.create()) {
+   *   String name = "name3373707";
+   *   Operation response = operationsClient.getOperation(name);
+   * }
+   * }
+ * + * @param name The name of the operation resource. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final Operation getOperation(String name) { + GetOperationRequest request = GetOperationRequest.newBuilder().setName(name).build(); + return getOperation(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Gets the latest state of a long-running operation. Clients can use this method to poll the + * operation result at intervals as recommended by the API service. + * + *

Sample code: + * + *

{@code
+   * try (OperationsClient operationsClient = OperationsClient.create()) {
+   *   GetOperationRequest request = GetOperationRequest.newBuilder().setName("name3373707").build();
+   *   Operation response = operationsClient.getOperation(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 Operation getOperation(GetOperationRequest request) { + return getOperationCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Gets the latest state of a long-running operation. Clients can use this method to poll the + * operation result at intervals as recommended by the API service. + * + *

Sample code: + * + *

{@code
+   * try (OperationsClient operationsClient = OperationsClient.create()) {
+   *   GetOperationRequest request = GetOperationRequest.newBuilder().setName("name3373707").build();
+   *   ApiFuture future = operationsClient.getOperationCallable().futureCall(request);
+   *   // Do something.
+   *   Operation response = future.get();
+   * }
+   * }
+ */ + public final UnaryCallable getOperationCallable() { + return stub.getOperationCallable(); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Deletes a long-running operation. This method indicates that the client is no longer interested + * in the operation result. It does not cancel the operation. If the server doesn't support this + * method, it returns `google.rpc.Code.UNIMPLEMENTED`. + * + *

Sample code: + * + *

{@code
+   * try (OperationsClient operationsClient = OperationsClient.create()) {
+   *   String name = "name3373707";
+   *   operationsClient.deleteOperation(name);
+   * }
+   * }
+ * + * @param name The name of the operation resource to be deleted. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final void deleteOperation(String name) { + DeleteOperationRequest request = DeleteOperationRequest.newBuilder().setName(name).build(); + deleteOperation(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Deletes a long-running operation. This method indicates that the client is no longer interested + * in the operation result. It does not cancel the operation. If the server doesn't support this + * method, it returns `google.rpc.Code.UNIMPLEMENTED`. + * + *

Sample code: + * + *

{@code
+   * try (OperationsClient operationsClient = OperationsClient.create()) {
+   *   DeleteOperationRequest request =
+   *       DeleteOperationRequest.newBuilder().setName("name3373707").build();
+   *   operationsClient.deleteOperation(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 void deleteOperation(DeleteOperationRequest request) { + deleteOperationCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Deletes a long-running operation. This method indicates that the client is no longer interested + * in the operation result. It does not cancel the operation. If the server doesn't support this + * method, it returns `google.rpc.Code.UNIMPLEMENTED`. + * + *

Sample code: + * + *

{@code
+   * try (OperationsClient operationsClient = OperationsClient.create()) {
+   *   DeleteOperationRequest request =
+   *       DeleteOperationRequest.newBuilder().setName("name3373707").build();
+   *   ApiFuture future = operationsClient.deleteOperationCallable().futureCall(request);
+   *   // Do something.
+   *   future.get();
+   * }
+   * }
+ */ + public final UnaryCallable deleteOperationCallable() { + return stub.deleteOperationCallable(); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Starts asynchronous cancellation on a long-running operation. The server makes a best effort to + * cancel the operation, but success is not guaranteed. If the server doesn't support this method, + * it returns `google.rpc.Code.UNIMPLEMENTED`. Clients can use + * [Operations.GetOperation][google.longrunning.Operations.GetOperation] or other methods to check + * whether the cancellation succeeded or whether the operation completed despite cancellation. On + * successful cancellation, the operation is not deleted; instead, it becomes an operation with an + * [Operation.error][google.longrunning.Operation.error] value with a + * [google.rpc.Status.code][google.rpc.Status.code] of 1, corresponding to `Code.CANCELLED`. + * + *

Sample code: + * + *

{@code
+   * try (OperationsClient operationsClient = OperationsClient.create()) {
+   *   String name = "name3373707";
+   *   operationsClient.cancelOperation(name);
+   * }
+   * }
+ * + * @param name The name of the operation resource to be cancelled. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final void cancelOperation(String name) { + CancelOperationRequest request = CancelOperationRequest.newBuilder().setName(name).build(); + cancelOperation(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Starts asynchronous cancellation on a long-running operation. The server makes a best effort to + * cancel the operation, but success is not guaranteed. If the server doesn't support this method, + * it returns `google.rpc.Code.UNIMPLEMENTED`. Clients can use + * [Operations.GetOperation][google.longrunning.Operations.GetOperation] or other methods to check + * whether the cancellation succeeded or whether the operation completed despite cancellation. On + * successful cancellation, the operation is not deleted; instead, it becomes an operation with an + * [Operation.error][google.longrunning.Operation.error] value with a + * [google.rpc.Status.code][google.rpc.Status.code] of 1, corresponding to `Code.CANCELLED`. + * + *

Sample code: + * + *

{@code
+   * try (OperationsClient operationsClient = OperationsClient.create()) {
+   *   CancelOperationRequest request =
+   *       CancelOperationRequest.newBuilder().setName("name3373707").build();
+   *   operationsClient.cancelOperation(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 void cancelOperation(CancelOperationRequest request) { + cancelOperationCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Starts asynchronous cancellation on a long-running operation. The server makes a best effort to + * cancel the operation, but success is not guaranteed. If the server doesn't support this method, + * it returns `google.rpc.Code.UNIMPLEMENTED`. Clients can use + * [Operations.GetOperation][google.longrunning.Operations.GetOperation] or other methods to check + * whether the cancellation succeeded or whether the operation completed despite cancellation. On + * successful cancellation, the operation is not deleted; instead, it becomes an operation with an + * [Operation.error][google.longrunning.Operation.error] value with a + * [google.rpc.Status.code][google.rpc.Status.code] of 1, corresponding to `Code.CANCELLED`. + * + *

Sample code: + * + *

{@code
+   * try (OperationsClient operationsClient = OperationsClient.create()) {
+   *   CancelOperationRequest request =
+   *       CancelOperationRequest.newBuilder().setName("name3373707").build();
+   *   ApiFuture future = operationsClient.cancelOperationCallable().futureCall(request);
+   *   // Do something.
+   *   future.get();
+   * }
+   * }
+ */ + public final UnaryCallable cancelOperationCallable() { + return stub.cancelOperationCallable(); + } + + @Override + public final void close() { + stub.close(); + } + + @Override + public void shutdown() { + stub.shutdown(); + } + + @Override + public boolean isShutdown() { + return stub.isShutdown(); + } + + @Override + public boolean isTerminated() { + return stub.isTerminated(); + } + + @Override + public void shutdownNow() { + stub.shutdownNow(); + } + + @Override + public boolean awaitTermination(long duration, TimeUnit unit) throws InterruptedException { + return stub.awaitTermination(duration, unit); + } + + public static class ListOperationsPagedResponse + extends AbstractPagedListResponse< + ListOperationsRequest, + ListOperationsResponse, + Operation, + ListOperationsPage, + ListOperationsFixedSizeCollection> { + + public static ApiFuture createAsync( + PageContext context, + ApiFuture futureResponse) { + ApiFuture futurePage = + ListOperationsPage.createEmptyPage().createPageAsync(context, futureResponse); + return ApiFutures.transform( + futurePage, + new ApiFunction() { + @Override + public ListOperationsPagedResponse apply(ListOperationsPage input) { + return new ListOperationsPagedResponse(input); + } + }, + MoreExecutors.directExecutor()); + } + + private ListOperationsPagedResponse(ListOperationsPage page) { + super(page, ListOperationsFixedSizeCollection.createEmptyCollection()); + } + } + + public static class ListOperationsPage + extends AbstractPage< + ListOperationsRequest, ListOperationsResponse, Operation, ListOperationsPage> { + + private ListOperationsPage( + PageContext context, + ListOperationsResponse response) { + super(context, response); + } + + private static ListOperationsPage createEmptyPage() { + return new ListOperationsPage(null, null); + } + + @Override + protected ListOperationsPage createPage( + PageContext context, + ListOperationsResponse response) { + return new ListOperationsPage(context, response); + } + + @Override + public ApiFuture createPageAsync( + PageContext context, + ApiFuture futureResponse) { + return super.createPageAsync(context, futureResponse); + } + } + + public static class ListOperationsFixedSizeCollection + extends AbstractFixedSizeCollection< + ListOperationsRequest, + ListOperationsResponse, + Operation, + ListOperationsPage, + ListOperationsFixedSizeCollection> { + + private ListOperationsFixedSizeCollection(List pages, int collectionSize) { + super(pages, collectionSize); + } + + private static ListOperationsFixedSizeCollection createEmptyCollection() { + return new ListOperationsFixedSizeCollection(null, 0); + } + + @Override + protected ListOperationsFixedSizeCollection createCollection( + List pages, int collectionSize) { + return new ListOperationsFixedSizeCollection(pages, collectionSize); + } + } +} diff --git a/gax-httpjson/src/main/java/com/google/api/gax/httpjson/longrunning/OperationsSettings.java b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/longrunning/OperationsSettings.java new file mode 100644 index 000000000..42afe6c9f --- /dev/null +++ b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/longrunning/OperationsSettings.java @@ -0,0 +1,239 @@ +/* + * Copyright 2021 Google LLC + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google LLC nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.google.api.gax.httpjson.longrunning; + +import static com.google.api.gax.httpjson.longrunning.OperationsClient.ListOperationsPagedResponse; + +import com.google.api.core.ApiFunction; +import com.google.api.core.BetaApi; +import com.google.api.gax.core.GoogleCredentialsProvider; +import com.google.api.gax.core.InstantiatingExecutorProvider; +import com.google.api.gax.httpjson.InstantiatingHttpJsonChannelProvider; +import com.google.api.gax.httpjson.longrunning.stub.OperationsStubSettings; +import com.google.api.gax.rpc.ApiClientHeaderProvider; +import com.google.api.gax.rpc.ClientContext; +import com.google.api.gax.rpc.ClientSettings; +import com.google.api.gax.rpc.PagedCallSettings; +import com.google.api.gax.rpc.TransportChannelProvider; +import com.google.api.gax.rpc.UnaryCallSettings; +import com.google.longrunning.CancelOperationRequest; +import com.google.longrunning.DeleteOperationRequest; +import com.google.longrunning.GetOperationRequest; +import com.google.longrunning.ListOperationsRequest; +import com.google.longrunning.ListOperationsResponse; +import com.google.longrunning.Operation; +import com.google.protobuf.Empty; +import java.io.IOException; +import java.util.List; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * Settings class to configure an instance of {@link OperationsClient}. + * + *

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

    + *
  • The default service address (longrunning.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 total timeout of getOperation to 30 seconds: + * + *

{@code
+ * OperationsSettings.Builder operationsSettingsBuilder = OperationsSettings.newBuilder();
+ * operationsSettingsBuilder
+ *     .getOperationSettings()
+ *     .setRetrySettings(
+ *         operationsSettingsBuilder
+ *             .getOperationSettings()
+ *             .getRetrySettings()
+ *             .toBuilder()
+ *             .setTotalTimeout(Duration.ofSeconds(30))
+ *             .build());
+ * OperationsSettings operationsSettings = operationsSettingsBuilder.build();
+ * }
+ */ +@Generated("by gapic-generator-java") +@BetaApi +public class OperationsSettings extends ClientSettings { + + /** Returns the object with the settings used for calls to listOperations. */ + public PagedCallSettings< + ListOperationsRequest, ListOperationsResponse, ListOperationsPagedResponse> + listOperationsSettings() { + return ((OperationsStubSettings) getStubSettings()).listOperationsSettings(); + } + + /** Returns the object with the settings used for calls to get. */ + public UnaryCallSettings getOperationSettings() { + return ((OperationsStubSettings) getStubSettings()).getOperationSettings(); + } + + /** Returns the object with the settings used for calls to delete. */ + public UnaryCallSettings deleteOperationSettings() { + return ((OperationsStubSettings) getStubSettings()).deleteOperationSettings(); + } + + /** Returns the object with the settings used for calls to cancel. */ + public UnaryCallSettings cancelOperationSettings() { + return ((OperationsStubSettings) getStubSettings()).cancelOperationSettings(); + } + + public static final OperationsSettings create(OperationsStubSettings stub) throws IOException { + return new OperationsSettings.Builder(stub.toBuilder()).build(); + } + + /** Returns a builder for the default ExecutorProvider for this service. */ + public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder() { + return OperationsStubSettings.defaultExecutorProviderBuilder(); + } + + /** Returns the default service endpoint. */ + public static String getDefaultEndpoint() { + return OperationsStubSettings.getDefaultEndpoint(); + } + + /** Returns the default service scopes. */ + public static List getDefaultServiceScopes() { + return OperationsStubSettings.getDefaultServiceScopes(); + } + + /** Returns a builder for the default credentials for this service. */ + public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { + return OperationsStubSettings.defaultCredentialsProviderBuilder(); + } + + /** Returns a builder for the default ChannelProvider for this service. */ + public static InstantiatingHttpJsonChannelProvider.Builder + defaultHttpJsonTransportProviderBuilder() { + return OperationsStubSettings.defaultHttpJsonTransportProviderBuilder(); + } + + public static TransportChannelProvider defaultTransportChannelProvider() { + return OperationsStubSettings.defaultTransportChannelProvider(); + } + + @BetaApi("The surface for customizing headers is not stable yet and may change in the future.") + public static ApiClientHeaderProvider.Builder defaultApiClientHeaderProviderBuilder() { + return OperationsStubSettings.defaultApiClientHeaderProviderBuilder(); + } + + /** 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 OperationsSettings(Builder settingsBuilder) throws IOException { + super(settingsBuilder); + } + + /** Builder for OperationsSettings. */ + public static class Builder extends ClientSettings.Builder { + + protected Builder() throws IOException { + this(((ClientContext) null)); + } + + protected Builder(ClientContext clientContext) { + super(OperationsStubSettings.newBuilder(clientContext)); + } + + protected Builder(OperationsSettings settings) { + super(settings.getStubSettings().toBuilder()); + } + + protected Builder(OperationsStubSettings.Builder stubSettings) { + super(stubSettings); + } + + private static Builder createDefault() { + return new Builder(OperationsStubSettings.newBuilder()); + } + + public OperationsStubSettings.Builder getStubSettingsBuilder() { + return ((OperationsStubSettings.Builder) getStubSettings()); + } + + // NEXT_MAJOR_VER: remove 'throws Exception'. + /** + * 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) throws Exception { + super.applyToAllUnaryMethods( + getStubSettingsBuilder().unaryMethodSettingsBuilders(), settingsUpdater); + return this; + } + + /** Returns the builder for the settings used for calls to listOperations. */ + public PagedCallSettings.Builder< + ListOperationsRequest, ListOperationsResponse, ListOperationsPagedResponse> + listOperationsSettings() { + return getStubSettingsBuilder().listOperationsSettings(); + } + + /** Returns the builder for the settings used for calls to get. */ + public UnaryCallSettings.Builder getOperationSettings() { + return getStubSettingsBuilder().getOperationSettings(); + } + + /** Returns the builder for the settings used for calls to delete. */ + public UnaryCallSettings.Builder deleteOperationSettings() { + return getStubSettingsBuilder().deleteOperationSettings(); + } + + /** Returns the builder for the settings used for calls to cancel. */ + public UnaryCallSettings.Builder cancelOperationSettings() { + return getStubSettingsBuilder().cancelOperationSettings(); + } + + @Override + public OperationsSettings build() throws IOException { + return new OperationsSettings(this); + } + } +} diff --git a/gax-httpjson/src/main/java/com/google/api/gax/httpjson/longrunning/stub/HttpJsonOperationsCallableFactory.java b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/longrunning/stub/HttpJsonOperationsCallableFactory.java new file mode 100644 index 000000000..dc279501c --- /dev/null +++ b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/longrunning/stub/HttpJsonOperationsCallableFactory.java @@ -0,0 +1,97 @@ +/* + * Copyright 2021 Google LLC + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google LLC nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.google.api.gax.httpjson.longrunning.stub; + +import com.google.api.core.BetaApi; +import com.google.api.gax.core.BackgroundResource; +import com.google.api.gax.httpjson.ApiMessage; +import com.google.api.gax.httpjson.HttpJsonCallSettings; +import com.google.api.gax.httpjson.HttpJsonCallableFactory; +import com.google.api.gax.httpjson.HttpJsonStubCallableFactory; +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.UnaryCallSettings; +import com.google.api.gax.rpc.UnaryCallable; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * REST callable factory implementation for the Operations service API. + * + *

This class is for advanced usage. + */ +@Generated("by gapic-generator-java") +@BetaApi +public class HttpJsonOperationsCallableFactory + 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, + BackgroundResource operationsStub) { + return null; + } +} diff --git a/gax-httpjson/src/main/java/com/google/api/gax/httpjson/longrunning/stub/HttpJsonOperationsStub.java b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/longrunning/stub/HttpJsonOperationsStub.java new file mode 100644 index 000000000..9b57dd899 --- /dev/null +++ b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/longrunning/stub/HttpJsonOperationsStub.java @@ -0,0 +1,401 @@ +/* + * Copyright 2021 Google LLC + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google LLC nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.google.api.gax.httpjson.longrunning.stub; + +import static com.google.api.gax.httpjson.longrunning.OperationsClient.ListOperationsPagedResponse; + +import com.google.api.client.http.HttpMethods; +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.FieldsExtractor; +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.longrunning.CancelOperationRequest; +import com.google.longrunning.DeleteOperationRequest; +import com.google.longrunning.GetOperationRequest; +import com.google.longrunning.ListOperationsRequest; +import com.google.longrunning.ListOperationsResponse; +import com.google.longrunning.Operation; +import com.google.protobuf.Empty; +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 Operations service API. + * + *

This class is for advanced usage and reflects the underlying API directly. + */ +@Generated("by gapic-generator-java") +@BetaApi("A restructuring of stub classes is planned, so this may break in the future") +public class HttpJsonOperationsStub extends OperationsStub { + private static final ApiMethodDescriptor + listOperationsMethodDescriptor = + ApiMethodDescriptor.newBuilder() + .setFullMethodName("google.longrunning.Operations/ListOperations") + .setHttpMethod(HttpMethods.GET) + .setRequestFormatter( + ProtoMessageRequestFormatter.newBuilder() + .setPath( + "/v1/{name=operations}", + new FieldsExtractor>() { + @Override + public Map extract(ListOperationsRequest request) { + Map fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putPathParam(fields, "name", request.getName()); + return fields; + } + }) + .setQueryParamsExtractor( + new FieldsExtractor>>() { + @Override + public Map> extract( + ListOperationsRequest request) { + Map> fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putQueryParam(fields, "filter", request.getFilter()); + serializer.putQueryParam(fields, "pageSize", request.getPageSize()); + serializer.putQueryParam(fields, "pageToken", request.getPageToken()); + return fields; + } + }) + .setRequestBodyExtractor( + new FieldsExtractor() { + @Override + public String extract(ListOperationsRequest request) { + return null; + } + }) + .build()) + .setResponseParser( + ProtoMessageResponseParser.newBuilder() + .setDefaultInstance(ListOperationsResponse.getDefaultInstance()) + .build()) + .build(); + + private static final ApiMethodDescriptor + getOperationMethodDescriptor = + ApiMethodDescriptor.newBuilder() + .setFullMethodName("google.longrunning.Operations/GetOperation") + .setHttpMethod(HttpMethods.GET) + .setRequestFormatter( + ProtoMessageRequestFormatter.newBuilder() + .setPath( + "/v1/{name=operations/**}", + new FieldsExtractor>() { + @Override + public Map extract(GetOperationRequest request) { + Map fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putPathParam(fields, "name", request.getName()); + return fields; + } + }) + .setQueryParamsExtractor( + new FieldsExtractor>>() { + @Override + public Map> extract(GetOperationRequest request) { + Map> fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + return fields; + } + }) + .setRequestBodyExtractor( + new FieldsExtractor() { + @Override + public String extract(GetOperationRequest request) { + return null; + } + }) + .build()) + .setResponseParser( + ProtoMessageResponseParser.newBuilder() + .setDefaultInstance(Operation.getDefaultInstance()) + .build()) + .build(); + + private static final ApiMethodDescriptor + deleteOperationMethodDescriptor = + ApiMethodDescriptor.newBuilder() + .setFullMethodName("google.longrunning.Operations/DeleteOperation") + .setHttpMethod(HttpMethods.DELETE) + .setRequestFormatter( + ProtoMessageRequestFormatter.newBuilder() + .setPath( + "/v1/{name=operations/**}", + new FieldsExtractor>() { + @Override + public Map extract(DeleteOperationRequest request) { + Map fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putPathParam(fields, "name", request.getName()); + return fields; + } + }) + .setQueryParamsExtractor( + new FieldsExtractor>>() { + @Override + public Map> extract( + DeleteOperationRequest request) { + Map> fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + return fields; + } + }) + .setRequestBodyExtractor( + new FieldsExtractor() { + @Override + public String extract(DeleteOperationRequest request) { + return null; + } + }) + .build()) + .setResponseParser( + ProtoMessageResponseParser.newBuilder() + .setDefaultInstance(Empty.getDefaultInstance()) + .build()) + .build(); + + private static final ApiMethodDescriptor + cancelOperationMethodDescriptor = + ApiMethodDescriptor.newBuilder() + .setFullMethodName("google.longrunning.Operations/CancelOperation") + .setHttpMethod(HttpMethods.POST) + .setRequestFormatter( + ProtoMessageRequestFormatter.newBuilder() + .setPath( + "/v1/{name=operations/**}:cancel", + new FieldsExtractor>() { + @Override + public Map extract(CancelOperationRequest request) { + Map fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putPathParam(fields, "name", request.getName()); + return fields; + } + }) + .setQueryParamsExtractor( + new FieldsExtractor>>() { + @Override + public Map> extract( + CancelOperationRequest request) { + Map> fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + return fields; + } + }) + .setRequestBodyExtractor( + new FieldsExtractor() { + @Override + public String extract(CancelOperationRequest request) { + return null; + } + }) + .build()) + .setResponseParser( + ProtoMessageResponseParser.newBuilder() + .setDefaultInstance(Empty.getDefaultInstance()) + .build()) + .build(); + + private final UnaryCallable listOperationsCallable; + private final UnaryCallable + listOperationsPagedCallable; + private final UnaryCallable getOperationCallable; + private final UnaryCallable deleteOperationCallable; + private final UnaryCallable cancelOperationCallable; + + private final BackgroundResource backgroundResources; + private final HttpJsonStubCallableFactory callableFactory; + + public static final HttpJsonOperationsStub create(OperationsStubSettings settings) + throws IOException { + return new HttpJsonOperationsStub(settings, ClientContext.create(settings)); + } + + public static final HttpJsonOperationsStub create(ClientContext clientContext) + throws IOException { + return new HttpJsonOperationsStub(OperationsStubSettings.newBuilder().build(), clientContext); + } + + public static final HttpJsonOperationsStub create( + ClientContext clientContext, HttpJsonStubCallableFactory callableFactory) throws IOException { + return new HttpJsonOperationsStub( + OperationsStubSettings.newBuilder().build(), clientContext, callableFactory); + } + + /** + * Constructs an instance of HttpJsonOperationsStub, 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 HttpJsonOperationsStub(OperationsStubSettings settings, ClientContext clientContext) + throws IOException { + this(settings, clientContext, new HttpJsonOperationsCallableFactory()); + } + + /** + * Constructs an instance of HttpJsonOperationsStub, 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 HttpJsonOperationsStub( + OperationsStubSettings settings, + ClientContext clientContext, + HttpJsonStubCallableFactory callableFactory) + throws IOException { + this.callableFactory = callableFactory; + + HttpJsonCallSettings + listOperationsTransportSettings = + HttpJsonCallSettings.newBuilder() + .setMethodDescriptor(listOperationsMethodDescriptor) + .build(); + HttpJsonCallSettings getOperationTransportSettings = + HttpJsonCallSettings.newBuilder() + .setMethodDescriptor(getOperationMethodDescriptor) + .build(); + HttpJsonCallSettings deleteOperationTransportSettings = + HttpJsonCallSettings.newBuilder() + .setMethodDescriptor(deleteOperationMethodDescriptor) + .build(); + HttpJsonCallSettings cancelOperationTransportSettings = + HttpJsonCallSettings.newBuilder() + .setMethodDescriptor(cancelOperationMethodDescriptor) + .build(); + + this.listOperationsCallable = + callableFactory.createUnaryCallable( + listOperationsTransportSettings, settings.listOperationsSettings(), clientContext); + this.listOperationsPagedCallable = + callableFactory.createPagedCallable( + listOperationsTransportSettings, settings.listOperationsSettings(), clientContext); + this.getOperationCallable = + callableFactory.createUnaryCallable( + getOperationTransportSettings, settings.getOperationSettings(), clientContext); + this.deleteOperationCallable = + callableFactory.createUnaryCallable( + deleteOperationTransportSettings, settings.deleteOperationSettings(), clientContext); + this.cancelOperationCallable = + callableFactory.createUnaryCallable( + cancelOperationTransportSettings, settings.cancelOperationSettings(), clientContext); + + this.backgroundResources = + new BackgroundResourceAggregation(clientContext.getBackgroundResources()); + } + + @InternalApi + public static List getMethodDescriptors() { + List methodDescriptors = new ArrayList<>(); + methodDescriptors.add(listOperationsMethodDescriptor); + methodDescriptors.add(getOperationMethodDescriptor); + methodDescriptors.add(deleteOperationMethodDescriptor); + methodDescriptors.add(cancelOperationMethodDescriptor); + return methodDescriptors; + } + + @Override + public UnaryCallable listOperationsCallable() { + return listOperationsCallable; + } + + @Override + public UnaryCallable + listOperationsPagedCallable() { + return listOperationsPagedCallable; + } + + @Override + public UnaryCallable getOperationCallable() { + return getOperationCallable; + } + + @Override + public UnaryCallable deleteOperationCallable() { + return deleteOperationCallable; + } + + @Override + public UnaryCallable cancelOperationCallable() { + return cancelOperationCallable; + } + + @Override + public final void close() { + shutdown(); + } + + @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/gax-httpjson/src/main/java/com/google/api/gax/httpjson/longrunning/stub/OperationsStub.java b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/longrunning/stub/OperationsStub.java new file mode 100644 index 000000000..148303177 --- /dev/null +++ b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/longrunning/stub/OperationsStub.java @@ -0,0 +1,78 @@ +/* + * Copyright 2021 Google LLC + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google LLC nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.google.api.gax.httpjson.longrunning.stub; + +import com.google.api.core.BetaApi; +import com.google.api.gax.core.BackgroundResource; +import com.google.api.gax.httpjson.longrunning.OperationsClient.ListOperationsPagedResponse; +import com.google.api.gax.rpc.UnaryCallable; +import com.google.longrunning.CancelOperationRequest; +import com.google.longrunning.DeleteOperationRequest; +import com.google.longrunning.GetOperationRequest; +import com.google.longrunning.ListOperationsRequest; +import com.google.longrunning.ListOperationsResponse; +import com.google.longrunning.Operation; +import com.google.protobuf.Empty; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * Base stub class for the Operations service API. + * + *

This class is for advanced usage and reflects the underlying API directly. + */ +@Generated("by gapic-generator-java") +@BetaApi +public abstract class OperationsStub implements BackgroundResource { + + public UnaryCallable + listOperationsPagedCallable() { + throw new UnsupportedOperationException("Not implemented: listOperationsPagedCallable()"); + } + + public UnaryCallable listOperationsCallable() { + throw new UnsupportedOperationException("Not implemented: listOperationsCallable()"); + } + + public UnaryCallable getOperationCallable() { + throw new UnsupportedOperationException("Not implemented: getOperationCallable()"); + } + + public UnaryCallable deleteOperationCallable() { + throw new UnsupportedOperationException("Not implemented: deleteOperationCallable()"); + } + + public UnaryCallable cancelOperationCallable() { + throw new UnsupportedOperationException("Not implemented: cancelOperationCallable()"); + } + + @Override + public abstract void close(); +} diff --git a/gax-httpjson/src/main/java/com/google/api/gax/httpjson/longrunning/stub/OperationsStubSettings.java b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/longrunning/stub/OperationsStubSettings.java new file mode 100644 index 000000000..679ab36a3 --- /dev/null +++ b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/longrunning/stub/OperationsStubSettings.java @@ -0,0 +1,431 @@ +/* + * Copyright 2021 Google LLC + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google LLC nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.google.api.gax.httpjson.longrunning.stub; + +import static com.google.api.gax.httpjson.longrunning.OperationsClient.ListOperationsPagedResponse; + +import com.google.api.core.ApiFunction; +import com.google.api.core.ApiFuture; +import com.google.api.core.BetaApi; +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.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; +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.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; +import com.google.longrunning.CancelOperationRequest; +import com.google.longrunning.DeleteOperationRequest; +import com.google.longrunning.GetOperationRequest; +import com.google.longrunning.ListOperationsRequest; +import com.google.longrunning.ListOperationsResponse; +import com.google.longrunning.Operation; +import com.google.protobuf.Empty; +import java.io.IOException; +import java.util.List; +import javax.annotation.Generated; +import org.threeten.bp.Duration; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * Settings class to configure an instance of {@link OperationsStub}. + * + *

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

    + *
  • The default service address (longrunning.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 total timeout of getOperation to 30 seconds: + * + *

{@code
+ * OperationsStubSettings.Builder operationsSettingsBuilder = OperationsStubSettings.newBuilder();
+ * operationsSettingsBuilder
+ *     .getOperationSettings()
+ *     .setRetrySettings(
+ *         operationsSettingsBuilder
+ *             .getOperationSettings()
+ *             .getRetrySettings()
+ *             .toBuilder()
+ *             .setTotalTimeout(Duration.ofSeconds(30))
+ *             .build());
+ * OperationsStubSettings operationsSettings = operationsSettingsBuilder.build();
+ * }
+ */ +@Generated("by gapic-generator-java") +@BetaApi +public class OperationsStubSettings extends StubSettings { + /** The default scopes of the service. */ + private static final ImmutableList DEFAULT_SERVICE_SCOPES = + ImmutableList.builder().build(); + + private final PagedCallSettings< + ListOperationsRequest, ListOperationsResponse, ListOperationsPagedResponse> + listOperationsSettings; + private final UnaryCallSettings getOperationSettings; + private final UnaryCallSettings deleteOperationSettings; + private final UnaryCallSettings cancelOperationSettings; + + private static final PagedListDescriptor + LIST_OPERATIONS_PAGE_STR_DESC = + new PagedListDescriptor() { + @Override + public String emptyToken() { + return ""; + } + + @Override + public ListOperationsRequest injectToken(ListOperationsRequest payload, String token) { + return ListOperationsRequest.newBuilder(payload).setPageToken(token).build(); + } + + @Override + public ListOperationsRequest injectPageSize( + ListOperationsRequest payload, int pageSize) { + return ListOperationsRequest.newBuilder(payload).setPageSize(pageSize).build(); + } + + @Override + public Integer extractPageSize(ListOperationsRequest payload) { + return payload.getPageSize(); + } + + @Override + public String extractNextToken(ListOperationsResponse payload) { + return payload.getNextPageToken(); + } + + @Override + public Iterable extractResources(ListOperationsResponse payload) { + return payload.getOperationsList() == null + ? ImmutableList.of() + : payload.getOperationsList(); + } + }; + + private static final PagedListResponseFactory< + ListOperationsRequest, ListOperationsResponse, ListOperationsPagedResponse> + LIST_OPERATIONS_PAGE_STR_FACT = + new PagedListResponseFactory< + ListOperationsRequest, ListOperationsResponse, ListOperationsPagedResponse>() { + @Override + public ApiFuture getFuturePagedResponse( + UnaryCallable callable, + ListOperationsRequest request, + ApiCallContext context, + ApiFuture futureResponse) { + PageContext pageContext = + PageContext.create(callable, LIST_OPERATIONS_PAGE_STR_DESC, request, context); + return ListOperationsPagedResponse.createAsync(pageContext, futureResponse); + } + }; + + /** Returns the object with the settings used for calls to listOperations. */ + public PagedCallSettings< + ListOperationsRequest, ListOperationsResponse, ListOperationsPagedResponse> + listOperationsSettings() { + return listOperationsSettings; + } + + /** Returns the object with the settings used for calls to get. */ + public UnaryCallSettings getOperationSettings() { + return getOperationSettings; + } + + /** Returns the object with the settings used for calls to delete. */ + public UnaryCallSettings deleteOperationSettings() { + return deleteOperationSettings; + } + + /** Returns the object with the settings used for calls to cancel. */ + public UnaryCallSettings cancelOperationSettings() { + return cancelOperationSettings; + } + + @BetaApi("A restructuring of stub classes is planned, so this may break in the future") + public OperationsStub createStub() throws IOException { + if (getTransportChannelProvider() + .getTransportName() + .equals(HttpJsonTransportChannel.getHttpJsonTransportName())) { + return HttpJsonOperationsStub.create(this); + } + throw new UnsupportedOperationException( + String.format( + "Transport not supported: %s", getTransportChannelProvider().getTransportName())); + } + + /** Returns a builder for the default ExecutorProvider for this service. */ + public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder() { + return InstantiatingExecutorProvider.newBuilder(); + } + + /** Returns the default service endpoint. */ + public static String getDefaultEndpoint() { + return "longrunning.googleapis.com:443"; + } + + /** Returns the default mTLS service endpoint. */ + public static String getDefaultMtlsEndpoint() { + return "longrunning.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); + } + + /** Returns a builder for the default ChannelProvider for this service. */ + public static InstantiatingHttpJsonChannelProvider.Builder + defaultHttpJsonTransportProviderBuilder() { + return InstantiatingHttpJsonChannelProvider.newBuilder(); + } + + public static TransportChannelProvider defaultTransportChannelProvider() { + return defaultHttpJsonTransportProviderBuilder().build(); + } + + @BetaApi("The surface for customizing headers is not stable yet and may change in the future.") + public static ApiClientHeaderProvider.Builder defaultApiClientHeaderProviderBuilder() { + return ApiClientHeaderProvider.newBuilder() + .setGeneratedLibToken( + "gapic", GaxProperties.getLibraryVersion(OperationsStubSettings.class)) + .setTransportToken( + GaxHttpJsonProperties.getHttpJsonTokenName(), + GaxHttpJsonProperties.getHttpJsonVersion()); + } + + /** 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 OperationsStubSettings(Builder settingsBuilder) throws IOException { + super(settingsBuilder); + + listOperationsSettings = settingsBuilder.listOperationsSettings().build(); + getOperationSettings = settingsBuilder.getOperationSettings().build(); + deleteOperationSettings = settingsBuilder.deleteOperationSettings().build(); + cancelOperationSettings = settingsBuilder.cancelOperationSettings().build(); + } + + /** Builder for OperationsStubSettings. */ + public static class Builder extends StubSettings.Builder { + private final ImmutableList> unaryMethodSettingsBuilders; + private final PagedCallSettings.Builder< + ListOperationsRequest, ListOperationsResponse, ListOperationsPagedResponse> + listOperationsSettings; + private final UnaryCallSettings.Builder getOperationSettings; + private final UnaryCallSettings.Builder deleteOperationSettings; + private final UnaryCallSettings.Builder cancelOperationSettings; + private static final ImmutableMap> + RETRYABLE_CODE_DEFINITIONS; + + static { + ImmutableMap.Builder> definitions = + ImmutableMap.builder(); + definitions.put( + "retry_policy_0_codes", + ImmutableSet.copyOf(Lists.newArrayList(StatusCode.Code.UNAVAILABLE))); + RETRYABLE_CODE_DEFINITIONS = definitions.build(); + } + + private static final ImmutableMap RETRY_PARAM_DEFINITIONS; + + static { + ImmutableMap.Builder definitions = ImmutableMap.builder(); + RetrySettings settings = null; + settings = + RetrySettings.newBuilder() + .setInitialRetryDelay(Duration.ofMillis(500L)) + .setRetryDelayMultiplier(2.0) + .setMaxRetryDelay(Duration.ofMillis(10000L)) + .setInitialRpcTimeout(Duration.ofMillis(10000L)) + .setRpcTimeoutMultiplier(1.0) + .setMaxRpcTimeout(Duration.ofMillis(10000L)) + .setTotalTimeout(Duration.ofMillis(10000L)) + .build(); + definitions.put("retry_policy_0_params", settings); + RETRY_PARAM_DEFINITIONS = definitions.build(); + } + + protected Builder() { + this(((ClientContext) null)); + } + + protected Builder(ClientContext clientContext) { + super(clientContext); + + listOperationsSettings = PagedCallSettings.newBuilder(LIST_OPERATIONS_PAGE_STR_FACT); + getOperationSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); + deleteOperationSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); + cancelOperationSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); + + unaryMethodSettingsBuilders = + ImmutableList.>of( + listOperationsSettings, + getOperationSettings, + deleteOperationSettings, + cancelOperationSettings); + initDefaults(this); + } + + protected Builder(OperationsStubSettings settings) { + super(settings); + + listOperationsSettings = settings.listOperationsSettings.toBuilder(); + getOperationSettings = settings.getOperationSettings.toBuilder(); + deleteOperationSettings = settings.deleteOperationSettings.toBuilder(); + cancelOperationSettings = settings.cancelOperationSettings.toBuilder(); + + unaryMethodSettingsBuilders = + ImmutableList.>of( + listOperationsSettings, + getOperationSettings, + deleteOperationSettings, + cancelOperationSettings); + } + + private static Builder createDefault() { + Builder builder = new Builder(((ClientContext) null)); + + builder.setTransportChannelProvider(defaultTransportChannelProvider()); + builder.setCredentialsProvider(defaultCredentialsProviderBuilder().build()); + builder.setInternalHeaderProvider(defaultApiClientHeaderProviderBuilder().build()); + builder.setEndpoint(getDefaultEndpoint()); + builder.setMtlsEndpoint(getDefaultMtlsEndpoint()); + builder.setSwitchToMtlsEndpointAllowed(true); + + return initDefaults(builder); + } + + private static Builder initDefaults(Builder builder) { + builder + .listOperationsSettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("retry_policy_0_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("retry_policy_0_params")); + + builder + .getOperationSettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("retry_policy_0_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("retry_policy_0_params")); + + builder + .deleteOperationSettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("retry_policy_0_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("retry_policy_0_params")); + + builder + .cancelOperationSettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("retry_policy_0_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("retry_policy_0_params")); + + return builder; + } + + // NEXT_MAJOR_VER: remove 'throws Exception'. + /** + * 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) throws Exception { + super.applyToAllUnaryMethods(unaryMethodSettingsBuilders, settingsUpdater); + return this; + } + + public ImmutableList> unaryMethodSettingsBuilders() { + return unaryMethodSettingsBuilders; + } + + /** Returns the builder for the settings used for calls to listOperations. */ + public PagedCallSettings.Builder< + ListOperationsRequest, ListOperationsResponse, ListOperationsPagedResponse> + listOperationsSettings() { + return listOperationsSettings; + } + + /** Returns the builder for the settings used for calls to get. */ + public UnaryCallSettings.Builder getOperationSettings() { + return getOperationSettings; + } + + /** Returns the builder for the settings used for calls to delete. */ + public UnaryCallSettings.Builder deleteOperationSettings() { + return deleteOperationSettings; + } + + /** Returns the builder for the settings used for calls to cancel. */ + public UnaryCallSettings.Builder cancelOperationSettings() { + return cancelOperationSettings; + } + + @Override + public OperationsStubSettings build() throws IOException { + return new OperationsStubSettings(this); + } + } +} diff --git a/gax-httpjson/src/test/java/com/google/api/gax/httpjson/HttpJsonLongRunningClientTest.java b/gax-httpjson/src/test/java/com/google/api/gax/httpjson/HttpJsonLongRunningClientTest.java new file mode 100644 index 000000000..702f327a6 --- /dev/null +++ b/gax-httpjson/src/test/java/com/google/api/gax/httpjson/HttpJsonLongRunningClientTest.java @@ -0,0 +1,146 @@ +/* + * Copyright 2021 Google LLC + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google LLC nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.google.api.gax.httpjson; + +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import com.google.api.core.ApiFuture; +import com.google.api.core.ApiFutures; +import com.google.api.gax.longrunning.OperationSnapshot; +import com.google.api.gax.rpc.ApiCallContext; +import com.google.api.gax.rpc.UnaryCallable; +import com.google.common.truth.Truth; +import com.google.protobuf.Field; +import com.google.protobuf.Option; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class HttpJsonLongRunningClientTest { + + private OperationSnapshotFactory operationSnapFact; + private PollingRequestFactory