diff --git a/test/integration/BUILD.bazel b/test/integration/BUILD.bazel index 84463a5614..addd91b3e8 100644 --- a/test/integration/BUILD.bazel +++ b/test/integration/BUILD.bazel @@ -30,6 +30,7 @@ INTEGRATION_TEST_LIBRARIES = [ "pubsub", # Special=case handling for "_deleted-topic_" resource name patterns. "logging", # Java package remapping in gapic.yaml. "redis", # Has a gapic.yaml. + "storage", # Exercises storage-specific edge cases. "library", # No gRPC service config. "compute", # REGAPIC test. ] @@ -43,6 +44,7 @@ API_GAPIC_TARGETS = { "pubsub": ":pubsub_java_gapic", "logging": "@com_google_googleapis//google/logging/v2:logging_java_gapic", "redis": "@com_google_googleapis//google/cloud/redis/v1beta1:redis_java_gapic", + "storage": "@com_google_googleapis//google/storage/v2:storage_java_gapic", "library": "@com_google_googleapis//google/example/library/v1:library_java_gapic", "compute": "@com_google_googleapis_discovery//google/cloud/compute/v1:compute_small_java_gapic", } @@ -100,6 +102,25 @@ java_gapic_assembly_gradle_pkg( ], ) +# Storage API. +java_gapic_test( + name = "storage_java_gapic_test_suite", + test_classes = [ + "com.google.storage.v2.StorageClientTest", + ], + runtime_deps = ["@com_google_googleapis//google/storage/v2:storage_java_gapic_test"], +) + +java_gapic_assembly_gradle_pkg( + name = "google-cloud-storage-v2-java", + deps = [ + "@com_google_googleapis//google/storage/v2:storage_java_gapic", + "@com_google_googleapis//google/storage/v2:storage_java_grpc", + "@com_google_googleapis//google/storage/v2:storage_java_proto", + "@com_google_googleapis//google/storage/v2:storage_proto", + ], +) + # Logging API java_gapic_test( name = "logging_java_gapic_test_suite", diff --git a/test/integration/goldens/storage/BUILD.bazel b/test/integration/goldens/storage/BUILD.bazel new file mode 100644 index 0000000000..2822013159 --- /dev/null +++ b/test/integration/goldens/storage/BUILD.bazel @@ -0,0 +1,12 @@ +package(default_visibility = ["//visibility:public"]) + +filegroup( + name = "goldens_files", + srcs = glob( + ["**/*"], + exclude = [ + "BUILD.bazel", + ".*.sw*", + ], + ), +) diff --git a/test/integration/goldens/storage/com/google/storage/v2/BucketName.java b/test/integration/goldens/storage/com/google/storage/v2/BucketName.java new file mode 100644 index 0000000000..7a00e63d2a --- /dev/null +++ b/test/integration/goldens/storage/com/google/storage/v2/BucketName.java @@ -0,0 +1,191 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.storage.v2; + +import com.google.api.pathtemplate.PathTemplate; +import com.google.api.resourcenames.ResourceName; +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableMap; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +@Generated("by gapic-generator-java") +public class BucketName implements ResourceName { + private static final PathTemplate PROJECT_BUCKET = + PathTemplate.createWithoutUrlEncoding("projects/{project}/buckets/{bucket}"); + private volatile Map fieldValuesMap; + private final String project; + private final String bucket; + + @Deprecated + protected BucketName() { + project = null; + bucket = null; + } + + private BucketName(Builder builder) { + project = Preconditions.checkNotNull(builder.getProject()); + bucket = Preconditions.checkNotNull(builder.getBucket()); + } + + public String getProject() { + return project; + } + + public String getBucket() { + return bucket; + } + + public static Builder newBuilder() { + return new Builder(); + } + + public Builder toBuilder() { + return new Builder(this); + } + + public static BucketName of(String project, String bucket) { + return newBuilder().setProject(project).setBucket(bucket).build(); + } + + public static String format(String project, String bucket) { + return newBuilder().setProject(project).setBucket(bucket).build().toString(); + } + + public static BucketName parse(String formattedString) { + if (formattedString.isEmpty()) { + return null; + } + Map matchMap = + PROJECT_BUCKET.validatedMatch( + formattedString, "BucketName.parse: formattedString not in valid format"); + return of(matchMap.get("project"), matchMap.get("bucket")); + } + + public static List parseList(List formattedStrings) { + List list = new ArrayList<>(formattedStrings.size()); + for (String formattedString : formattedStrings) { + list.add(parse(formattedString)); + } + return list; + } + + public static List toStringList(List values) { + List list = new ArrayList<>(values.size()); + for (BucketName value : values) { + if (value == null) { + list.add(""); + } else { + list.add(value.toString()); + } + } + return list; + } + + public static boolean isParsableFrom(String formattedString) { + return PROJECT_BUCKET.matches(formattedString); + } + + @Override + public Map getFieldValuesMap() { + if (fieldValuesMap == null) { + synchronized (this) { + if (fieldValuesMap == null) { + ImmutableMap.Builder fieldMapBuilder = ImmutableMap.builder(); + if (project != null) { + fieldMapBuilder.put("project", project); + } + if (bucket != null) { + fieldMapBuilder.put("bucket", bucket); + } + fieldValuesMap = fieldMapBuilder.build(); + } + } + } + return fieldValuesMap; + } + + public String getFieldValue(String fieldName) { + return getFieldValuesMap().get(fieldName); + } + + @Override + public String toString() { + return PROJECT_BUCKET.instantiate("project", project, "bucket", bucket); + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + if (o != null || getClass() == o.getClass()) { + BucketName that = ((BucketName) o); + return Objects.equals(this.project, that.project) && Objects.equals(this.bucket, that.bucket); + } + return false; + } + + @Override + public int hashCode() { + int h = 1; + h *= 1000003; + h ^= Objects.hashCode(project); + h *= 1000003; + h ^= Objects.hashCode(bucket); + return h; + } + + /** Builder for projects/{project}/buckets/{bucket}. */ + public static class Builder { + private String project; + private String bucket; + + protected Builder() {} + + public String getProject() { + return project; + } + + public String getBucket() { + return bucket; + } + + public Builder setProject(String project) { + this.project = project; + return this; + } + + public Builder setBucket(String bucket) { + this.bucket = bucket; + return this; + } + + private Builder(BucketName bucketName) { + this.project = bucketName.project; + this.bucket = bucketName.bucket; + } + + public BucketName build() { + return new BucketName(this); + } + } +} diff --git a/test/integration/goldens/storage/com/google/storage/v2/CryptoKeyName.java b/test/integration/goldens/storage/com/google/storage/v2/CryptoKeyName.java new file mode 100644 index 0000000000..987146bc65 --- /dev/null +++ b/test/integration/goldens/storage/com/google/storage/v2/CryptoKeyName.java @@ -0,0 +1,261 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.storage.v2; + +import com.google.api.pathtemplate.PathTemplate; +import com.google.api.resourcenames.ResourceName; +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableMap; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +@Generated("by gapic-generator-java") +public class CryptoKeyName implements ResourceName { + private static final PathTemplate PROJECT_LOCATION_KEY_RING_CRYPTO_KEY = + PathTemplate.createWithoutUrlEncoding( + "projects/{project}/locations/{location}/keyRings/{key_ring}/cryptoKeys/{crypto_key}"); + private volatile Map fieldValuesMap; + private final String project; + private final String location; + private final String keyRing; + private final String cryptoKey; + + @Deprecated + protected CryptoKeyName() { + project = null; + location = null; + keyRing = null; + cryptoKey = null; + } + + private CryptoKeyName(Builder builder) { + project = Preconditions.checkNotNull(builder.getProject()); + location = Preconditions.checkNotNull(builder.getLocation()); + keyRing = Preconditions.checkNotNull(builder.getKeyRing()); + cryptoKey = Preconditions.checkNotNull(builder.getCryptoKey()); + } + + public String getProject() { + return project; + } + + public String getLocation() { + return location; + } + + public String getKeyRing() { + return keyRing; + } + + public String getCryptoKey() { + return cryptoKey; + } + + public static Builder newBuilder() { + return new Builder(); + } + + public Builder toBuilder() { + return new Builder(this); + } + + public static CryptoKeyName of( + String project, String location, String keyRing, String cryptoKey) { + return newBuilder() + .setProject(project) + .setLocation(location) + .setKeyRing(keyRing) + .setCryptoKey(cryptoKey) + .build(); + } + + public static String format(String project, String location, String keyRing, String cryptoKey) { + return newBuilder() + .setProject(project) + .setLocation(location) + .setKeyRing(keyRing) + .setCryptoKey(cryptoKey) + .build() + .toString(); + } + + public static CryptoKeyName parse(String formattedString) { + if (formattedString.isEmpty()) { + return null; + } + Map matchMap = + PROJECT_LOCATION_KEY_RING_CRYPTO_KEY.validatedMatch( + formattedString, "CryptoKeyName.parse: formattedString not in valid format"); + return of( + matchMap.get("project"), + matchMap.get("location"), + matchMap.get("key_ring"), + matchMap.get("crypto_key")); + } + + public static List parseList(List formattedStrings) { + List list = new ArrayList<>(formattedStrings.size()); + for (String formattedString : formattedStrings) { + list.add(parse(formattedString)); + } + return list; + } + + public static List toStringList(List values) { + List list = new ArrayList<>(values.size()); + for (CryptoKeyName value : values) { + if (value == null) { + list.add(""); + } else { + list.add(value.toString()); + } + } + return list; + } + + public static boolean isParsableFrom(String formattedString) { + return PROJECT_LOCATION_KEY_RING_CRYPTO_KEY.matches(formattedString); + } + + @Override + public Map getFieldValuesMap() { + if (fieldValuesMap == null) { + synchronized (this) { + if (fieldValuesMap == null) { + ImmutableMap.Builder fieldMapBuilder = ImmutableMap.builder(); + if (project != null) { + fieldMapBuilder.put("project", project); + } + if (location != null) { + fieldMapBuilder.put("location", location); + } + if (keyRing != null) { + fieldMapBuilder.put("key_ring", keyRing); + } + if (cryptoKey != null) { + fieldMapBuilder.put("crypto_key", cryptoKey); + } + fieldValuesMap = fieldMapBuilder.build(); + } + } + } + return fieldValuesMap; + } + + public String getFieldValue(String fieldName) { + return getFieldValuesMap().get(fieldName); + } + + @Override + public String toString() { + return PROJECT_LOCATION_KEY_RING_CRYPTO_KEY.instantiate( + "project", project, "location", location, "key_ring", keyRing, "crypto_key", cryptoKey); + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + if (o != null || getClass() == o.getClass()) { + CryptoKeyName that = ((CryptoKeyName) o); + return Objects.equals(this.project, that.project) + && Objects.equals(this.location, that.location) + && Objects.equals(this.keyRing, that.keyRing) + && Objects.equals(this.cryptoKey, that.cryptoKey); + } + return false; + } + + @Override + public int hashCode() { + int h = 1; + h *= 1000003; + h ^= Objects.hashCode(project); + h *= 1000003; + h ^= Objects.hashCode(location); + h *= 1000003; + h ^= Objects.hashCode(keyRing); + h *= 1000003; + h ^= Objects.hashCode(cryptoKey); + return h; + } + + /** + * Builder for + * projects/{project}/locations/{location}/keyRings/{key_ring}/cryptoKeys/{crypto_key}. + */ + public static class Builder { + private String project; + private String location; + private String keyRing; + private String cryptoKey; + + protected Builder() {} + + public String getProject() { + return project; + } + + public String getLocation() { + return location; + } + + public String getKeyRing() { + return keyRing; + } + + public String getCryptoKey() { + return cryptoKey; + } + + public Builder setProject(String project) { + this.project = project; + return this; + } + + public Builder setLocation(String location) { + this.location = location; + return this; + } + + public Builder setKeyRing(String keyRing) { + this.keyRing = keyRing; + return this; + } + + public Builder setCryptoKey(String cryptoKey) { + this.cryptoKey = cryptoKey; + return this; + } + + private Builder(CryptoKeyName cryptoKeyName) { + this.project = cryptoKeyName.project; + this.location = cryptoKeyName.location; + this.keyRing = cryptoKeyName.keyRing; + this.cryptoKey = cryptoKeyName.cryptoKey; + } + + public CryptoKeyName build() { + return new CryptoKeyName(this); + } + } +} diff --git a/test/integration/goldens/storage/com/google/storage/v2/MockStorage.java b/test/integration/goldens/storage/com/google/storage/v2/MockStorage.java new file mode 100644 index 0000000000..dbaae70d75 --- /dev/null +++ b/test/integration/goldens/storage/com/google/storage/v2/MockStorage.java @@ -0,0 +1,59 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.storage.v2; + +import com.google.api.core.BetaApi; +import com.google.api.gax.grpc.testing.MockGrpcService; +import com.google.protobuf.AbstractMessage; +import io.grpc.ServerServiceDefinition; +import java.util.List; +import javax.annotation.Generated; + +@BetaApi +@Generated("by gapic-generator-java") +public class MockStorage implements MockGrpcService { + private final MockStorageImpl serviceImpl; + + public MockStorage() { + serviceImpl = new MockStorageImpl(); + } + + @Override + public List getRequests() { + return serviceImpl.getRequests(); + } + + @Override + public void addResponse(AbstractMessage response) { + serviceImpl.addResponse(response); + } + + @Override + public void addException(Exception exception) { + serviceImpl.addException(exception); + } + + @Override + public ServerServiceDefinition getServiceDefinition() { + return serviceImpl.bindService(); + } + + @Override + public void reset() { + serviceImpl.reset(); + } +} diff --git a/test/integration/goldens/storage/com/google/storage/v2/MockStorageImpl.java b/test/integration/goldens/storage/com/google/storage/v2/MockStorageImpl.java new file mode 100644 index 0000000000..a2787a85bd --- /dev/null +++ b/test/integration/goldens/storage/com/google/storage/v2/MockStorageImpl.java @@ -0,0 +1,161 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.storage.v2; + +import com.google.api.core.BetaApi; +import com.google.protobuf.AbstractMessage; +import com.google.storage.v2.StorageGrpc.StorageImplBase; +import io.grpc.stub.StreamObserver; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; +import javax.annotation.Generated; + +@BetaApi +@Generated("by gapic-generator-java") +public class MockStorageImpl extends StorageImplBase { + private List requests; + private Queue responses; + + public MockStorageImpl() { + requests = new ArrayList<>(); + responses = new LinkedList<>(); + } + + public List getRequests() { + return requests; + } + + public void addResponse(AbstractMessage response) { + responses.add(response); + } + + public void setResponses(List responses) { + this.responses = new LinkedList(responses); + } + + public void addException(Exception exception) { + responses.add(exception); + } + + public void reset() { + requests = new ArrayList<>(); + responses = new LinkedList<>(); + } + + @Override + public void readObject( + ReadObjectRequest request, StreamObserver responseObserver) { + java.lang.Object response = responses.poll(); + if (response instanceof ReadObjectResponse) { + requests.add(request); + responseObserver.onNext(((ReadObjectResponse) response)); + responseObserver.onCompleted(); + } else if (response instanceof Exception) { + responseObserver.onError(((Exception) response)); + } else { + responseObserver.onError( + new IllegalArgumentException( + String.format( + "Unrecognized response type %s for method ReadObject, expected %s or %s", + response == null ? "null" : response.getClass().getName(), + ReadObjectResponse.class.getName(), + Exception.class.getName()))); + } + } + + @Override + public StreamObserver writeObject( + final StreamObserver responseObserver) { + StreamObserver requestObserver = + new StreamObserver() { + @Override + public void onNext(WriteObjectRequest value) { + requests.add(value); + final java.lang.Object response = responses.remove(); + if (response instanceof WriteObjectResponse) { + responseObserver.onNext(((WriteObjectResponse) response)); + } else if (response instanceof Exception) { + responseObserver.onError(((Exception) response)); + } else { + responseObserver.onError( + new IllegalArgumentException( + String.format( + "Unrecognized response type %s for method WriteObject, expected %s or %s", + response == null ? "null" : response.getClass().getName(), + WriteObjectResponse.class.getName(), + Exception.class.getName()))); + } + } + + @Override + public void onError(Throwable t) { + responseObserver.onError(t); + } + + @Override + public void onCompleted() { + responseObserver.onCompleted(); + } + }; + return requestObserver; + } + + @Override + public void startResumableWrite( + StartResumableWriteRequest request, + StreamObserver responseObserver) { + java.lang.Object response = responses.poll(); + if (response instanceof StartResumableWriteResponse) { + requests.add(request); + responseObserver.onNext(((StartResumableWriteResponse) response)); + responseObserver.onCompleted(); + } else if (response instanceof Exception) { + responseObserver.onError(((Exception) response)); + } else { + responseObserver.onError( + new IllegalArgumentException( + String.format( + "Unrecognized response type %s for method StartResumableWrite, expected %s or %s", + response == null ? "null" : response.getClass().getName(), + StartResumableWriteResponse.class.getName(), + Exception.class.getName()))); + } + } + + @Override + public void queryWriteStatus( + QueryWriteStatusRequest request, StreamObserver responseObserver) { + java.lang.Object response = responses.poll(); + if (response instanceof QueryWriteStatusResponse) { + requests.add(request); + responseObserver.onNext(((QueryWriteStatusResponse) response)); + responseObserver.onCompleted(); + } else if (response instanceof Exception) { + responseObserver.onError(((Exception) response)); + } else { + responseObserver.onError( + new IllegalArgumentException( + String.format( + "Unrecognized response type %s for method QueryWriteStatus, expected %s or %s", + response == null ? "null" : response.getClass().getName(), + QueryWriteStatusResponse.class.getName(), + Exception.class.getName()))); + } + } +} diff --git a/test/integration/goldens/storage/com/google/storage/v2/ProjectName.java b/test/integration/goldens/storage/com/google/storage/v2/ProjectName.java new file mode 100644 index 0000000000..d9cbaa5efa --- /dev/null +++ b/test/integration/goldens/storage/com/google/storage/v2/ProjectName.java @@ -0,0 +1,168 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.storage.v2; + +import com.google.api.pathtemplate.PathTemplate; +import com.google.api.resourcenames.ResourceName; +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableMap; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +@Generated("by gapic-generator-java") +public class ProjectName implements ResourceName { + private static final PathTemplate PROJECT = + PathTemplate.createWithoutUrlEncoding("projects/{project}"); + private volatile Map fieldValuesMap; + private final String project; + + @Deprecated + protected ProjectName() { + project = null; + } + + private ProjectName(Builder builder) { + project = Preconditions.checkNotNull(builder.getProject()); + } + + public String getProject() { + return project; + } + + public static Builder newBuilder() { + return new Builder(); + } + + public Builder toBuilder() { + return new Builder(this); + } + + public static ProjectName of(String project) { + return newBuilder().setProject(project).build(); + } + + public static String format(String project) { + return newBuilder().setProject(project).build().toString(); + } + + public static ProjectName parse(String formattedString) { + if (formattedString.isEmpty()) { + return null; + } + Map matchMap = + PROJECT.validatedMatch( + formattedString, "ProjectName.parse: formattedString not in valid format"); + return of(matchMap.get("project")); + } + + public static List parseList(List formattedStrings) { + List list = new ArrayList<>(formattedStrings.size()); + for (String formattedString : formattedStrings) { + list.add(parse(formattedString)); + } + return list; + } + + public static List toStringList(List values) { + List list = new ArrayList<>(values.size()); + for (ProjectName value : values) { + if (value == null) { + list.add(""); + } else { + list.add(value.toString()); + } + } + return list; + } + + public static boolean isParsableFrom(String formattedString) { + return PROJECT.matches(formattedString); + } + + @Override + public Map getFieldValuesMap() { + if (fieldValuesMap == null) { + synchronized (this) { + if (fieldValuesMap == null) { + ImmutableMap.Builder fieldMapBuilder = ImmutableMap.builder(); + if (project != null) { + fieldMapBuilder.put("project", project); + } + fieldValuesMap = fieldMapBuilder.build(); + } + } + } + return fieldValuesMap; + } + + public String getFieldValue(String fieldName) { + return getFieldValuesMap().get(fieldName); + } + + @Override + public String toString() { + return PROJECT.instantiate("project", project); + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + if (o != null || getClass() == o.getClass()) { + ProjectName that = ((ProjectName) o); + return Objects.equals(this.project, that.project); + } + return false; + } + + @Override + public int hashCode() { + int h = 1; + h *= 1000003; + h ^= Objects.hashCode(project); + return h; + } + + /** Builder for projects/{project}. */ + public static class Builder { + private String project; + + protected Builder() {} + + public String getProject() { + return project; + } + + public Builder setProject(String project) { + this.project = project; + return this; + } + + private Builder(ProjectName projectName) { + this.project = projectName.project; + } + + public ProjectName build() { + return new ProjectName(this); + } + } +} diff --git a/test/integration/goldens/storage/com/google/storage/v2/StorageClient.java b/test/integration/goldens/storage/com/google/storage/v2/StorageClient.java new file mode 100644 index 0000000000..78b7fd7e08 --- /dev/null +++ b/test/integration/goldens/storage/com/google/storage/v2/StorageClient.java @@ -0,0 +1,428 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.storage.v2; + +import com.google.api.core.BetaApi; +import com.google.api.gax.core.BackgroundResource; +import com.google.api.gax.rpc.ClientStreamingCallable; +import com.google.api.gax.rpc.ServerStreamingCallable; +import com.google.api.gax.rpc.UnaryCallable; +import com.google.storage.v2.stub.StorageStub; +import com.google.storage.v2.stub.StorageStubSettings; +import java.io.IOException; +import java.util.concurrent.TimeUnit; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * Service Description: Manages Google Cloud Storage resources. + * + *

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 (StorageClient storageClient = StorageClient.create()) {
+ *   StartResumableWriteRequest request =
+ *       StartResumableWriteRequest.newBuilder()
+ *           .setWriteObjectSpec(WriteObjectSpec.newBuilder().build())
+ *           .setCommonObjectRequestParams(CommonObjectRequestParams.newBuilder().build())
+ *           .setCommonRequestParams(CommonRequestParams.newBuilder().build())
+ *           .build();
+ *   StartResumableWriteResponse response = storageClient.startResumableWrite(request);
+ * }
+ * }
+ * + *

Note: close() needs to be called on the StorageClient 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 StorageSettings to create(). + * For example: + * + *

To customize credentials: + * + *

{@code
+ * StorageSettings storageSettings =
+ *     StorageSettings.newBuilder()
+ *         .setCredentialsProvider(FixedCredentialsProvider.create(myCredentials))
+ *         .build();
+ * StorageClient storageClient = StorageClient.create(storageSettings);
+ * }
+ * + *

To customize the endpoint: + * + *

{@code
+ * StorageSettings storageSettings = StorageSettings.newBuilder().setEndpoint(myEndpoint).build();
+ * StorageClient storageClient = StorageClient.create(storageSettings);
+ * }
+ * + *

Please refer to the GitHub repository's samples for more quickstart code snippets. + */ +@Generated("by gapic-generator-java") +public class StorageClient implements BackgroundResource { + private final StorageSettings settings; + private final StorageStub stub; + + /** Constructs an instance of StorageClient with default settings. */ + public static final StorageClient create() throws IOException { + return create(StorageSettings.newBuilder().build()); + } + + /** + * Constructs an instance of StorageClient, 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 StorageClient create(StorageSettings settings) throws IOException { + return new StorageClient(settings); + } + + /** + * Constructs an instance of StorageClient, using the given stub for making calls. This is for + * advanced usage - prefer using create(StorageSettings). + */ + @BetaApi("A restructuring of stub classes is planned, so this may break in the future") + public static final StorageClient create(StorageStub stub) { + return new StorageClient(stub); + } + + /** + * Constructs an instance of StorageClient, 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 StorageClient(StorageSettings settings) throws IOException { + this.settings = settings; + this.stub = ((StorageStubSettings) settings.getStubSettings()).createStub(); + } + + @BetaApi("A restructuring of stub classes is planned, so this may break in the future") + protected StorageClient(StorageStub stub) { + this.settings = null; + this.stub = stub; + } + + public final StorageSettings getSettings() { + return settings; + } + + @BetaApi("A restructuring of stub classes is planned, so this may break in the future") + public StorageStub getStub() { + return stub; + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Reads an object's data. + * + *

Sample code: + * + *

{@code
+   * try (StorageClient storageClient = StorageClient.create()) {
+   *   ReadObjectRequest request =
+   *       ReadObjectRequest.newBuilder()
+   *           .setBucket("bucket-1378203158")
+   *           .setObject("object-1023368385")
+   *           .setGeneration(305703192)
+   *           .setReadOffset(-715377828)
+   *           .setReadLimit(-164298798)
+   *           .setIfGenerationMatch(-1086241088)
+   *           .setIfGenerationNotMatch(1475720404)
+   *           .setIfMetagenerationMatch(1043427781)
+   *           .setIfMetagenerationNotMatch(1025430873)
+   *           .setCommonObjectRequestParams(CommonObjectRequestParams.newBuilder().build())
+   *           .setCommonRequestParams(CommonRequestParams.newBuilder().build())
+   *           .setReadMask(FieldMask.newBuilder().build())
+   *           .build();
+   *   ServerStream stream = storageClient.readObjectCallable().call(request);
+   *   for (ReadObjectResponse response : stream) {
+   *     // Do something when a response is received.
+   *   }
+   * }
+   * }
+ */ + public final ServerStreamingCallable readObjectCallable() { + return stub.readObjectCallable(); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Stores a new object and metadata. + * + *

An object can be written either in a single message stream or in a resumable sequence of + * message streams. To write using a single stream, the client should include in the first message + * of the stream an `WriteObjectSpec` describing the destination bucket, object, and any + * preconditions. Additionally, the final message must set 'finish_write' to true, or else it is + * an error. + * + *

For a resumable write, the client should instead call `StartResumableWrite()` and provide + * that method an `WriteObjectSpec.` They should then attach the returned `upload_id` to the first + * message of each following call to `Create`. If there is an error or the connection is broken + * during the resumable `Create()`, the client should check the status of the `Create()` by + * calling `QueryWriteStatus()` and continue writing from the returned `committed_size`. This may + * be less than the amount of data the client previously sent. + * + *

The service will not view the object as complete until the client has sent a + * `WriteObjectRequest` with `finish_write` set to `true`. Sending any requests on a stream after + * sending a request with `finish_write` set to `true` will cause an error. The client + * **should** check the response it receives to determine how much data the + * service was able to commit and whether the service views the object as complete. + * + *

Sample code: + * + *

{@code
+   * try (StorageClient storageClient = StorageClient.create()) {
+   *   ApiStreamObserver responseObserver =
+   *       new ApiStreamObserver() {
+   *         {@literal @}Override
+   *         public void onNext(WriteObjectResponse response) {
+   *           // Do something when a response is received.
+   *         }
+   *
+   *         {@literal @}Override
+   *         public void onError(Throwable t) {
+   *           // Add error-handling
+   *         }
+   *
+   *         {@literal @}Override
+   *         public void onCompleted() {
+   *           // Do something when complete.
+   *         }
+   *       };
+   *   ApiStreamObserver requestObserver =
+   *       storageClient.writeObject().clientStreamingCall(responseObserver);
+   *   WriteObjectRequest request =
+   *       WriteObjectRequest.newBuilder()
+   *           .setWriteOffset(-1559543565)
+   *           .setObjectChecksums(ObjectChecksums.newBuilder().build())
+   *           .setFinishWrite(true)
+   *           .setCommonObjectRequestParams(CommonObjectRequestParams.newBuilder().build())
+   *           .setCommonRequestParams(CommonRequestParams.newBuilder().build())
+   *           .build();
+   *   requestObserver.onNext(request);
+   * }
+   * }
+ */ + public final ClientStreamingCallable + writeObjectCallable() { + return stub.writeObjectCallable(); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Starts a resumable write. How long the write operation remains valid, and what happens when the + * write operation becomes invalid, are service-dependent. + * + *

Sample code: + * + *

{@code
+   * try (StorageClient storageClient = StorageClient.create()) {
+   *   StartResumableWriteRequest request =
+   *       StartResumableWriteRequest.newBuilder()
+   *           .setWriteObjectSpec(WriteObjectSpec.newBuilder().build())
+   *           .setCommonObjectRequestParams(CommonObjectRequestParams.newBuilder().build())
+   *           .setCommonRequestParams(CommonRequestParams.newBuilder().build())
+   *           .build();
+   *   StartResumableWriteResponse response = storageClient.startResumableWrite(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 StartResumableWriteResponse startResumableWrite(StartResumableWriteRequest request) { + return startResumableWriteCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Starts a resumable write. How long the write operation remains valid, and what happens when the + * write operation becomes invalid, are service-dependent. + * + *

Sample code: + * + *

{@code
+   * try (StorageClient storageClient = StorageClient.create()) {
+   *   StartResumableWriteRequest request =
+   *       StartResumableWriteRequest.newBuilder()
+   *           .setWriteObjectSpec(WriteObjectSpec.newBuilder().build())
+   *           .setCommonObjectRequestParams(CommonObjectRequestParams.newBuilder().build())
+   *           .setCommonRequestParams(CommonRequestParams.newBuilder().build())
+   *           .build();
+   *   ApiFuture future =
+   *       storageClient.startResumableWriteCallable().futureCall(request);
+   *   // Do something.
+   *   StartResumableWriteResponse response = future.get();
+   * }
+   * }
+ */ + public final UnaryCallable + startResumableWriteCallable() { + return stub.startResumableWriteCallable(); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Determines the `committed_size` for an object that is being written, which can then be used as + * the `write_offset` for the next `Write()` call. + * + *

If the object does not exist (i.e., the object has been deleted, or the first `Write()` has + * not yet reached the service), this method returns the error `NOT_FOUND`. + * + *

The client **may** call `QueryWriteStatus()` at any time to determine how + * much data has been processed for this object. This is useful if the client is buffering data + * and needs to know which data can be safely evicted. For any sequence of `QueryWriteStatus()` + * calls for a given object name, the sequence of returned `committed_size` values will be + * non-decreasing. + * + *

Sample code: + * + *

{@code
+   * try (StorageClient storageClient = StorageClient.create()) {
+   *   String uploadId = "uploadId1563990780";
+   *   QueryWriteStatusResponse response = storageClient.queryWriteStatus(uploadId);
+   * }
+   * }
+ * + * @param uploadId Required. The name of the resume token for the object whose write status is + * being requested. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final QueryWriteStatusResponse queryWriteStatus(String uploadId) { + QueryWriteStatusRequest request = + QueryWriteStatusRequest.newBuilder().setUploadId(uploadId).build(); + return queryWriteStatus(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Determines the `committed_size` for an object that is being written, which can then be used as + * the `write_offset` for the next `Write()` call. + * + *

If the object does not exist (i.e., the object has been deleted, or the first `Write()` has + * not yet reached the service), this method returns the error `NOT_FOUND`. + * + *

The client **may** call `QueryWriteStatus()` at any time to determine how + * much data has been processed for this object. This is useful if the client is buffering data + * and needs to know which data can be safely evicted. For any sequence of `QueryWriteStatus()` + * calls for a given object name, the sequence of returned `committed_size` values will be + * non-decreasing. + * + *

Sample code: + * + *

{@code
+   * try (StorageClient storageClient = StorageClient.create()) {
+   *   QueryWriteStatusRequest request =
+   *       QueryWriteStatusRequest.newBuilder()
+   *           .setUploadId("uploadId1563990780")
+   *           .setCommonObjectRequestParams(CommonObjectRequestParams.newBuilder().build())
+   *           .setCommonRequestParams(CommonRequestParams.newBuilder().build())
+   *           .build();
+   *   QueryWriteStatusResponse response = storageClient.queryWriteStatus(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 QueryWriteStatusResponse queryWriteStatus(QueryWriteStatusRequest request) { + return queryWriteStatusCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Determines the `committed_size` for an object that is being written, which can then be used as + * the `write_offset` for the next `Write()` call. + * + *

If the object does not exist (i.e., the object has been deleted, or the first `Write()` has + * not yet reached the service), this method returns the error `NOT_FOUND`. + * + *

The client **may** call `QueryWriteStatus()` at any time to determine how + * much data has been processed for this object. This is useful if the client is buffering data + * and needs to know which data can be safely evicted. For any sequence of `QueryWriteStatus()` + * calls for a given object name, the sequence of returned `committed_size` values will be + * non-decreasing. + * + *

Sample code: + * + *

{@code
+   * try (StorageClient storageClient = StorageClient.create()) {
+   *   QueryWriteStatusRequest request =
+   *       QueryWriteStatusRequest.newBuilder()
+   *           .setUploadId("uploadId1563990780")
+   *           .setCommonObjectRequestParams(CommonObjectRequestParams.newBuilder().build())
+   *           .setCommonRequestParams(CommonRequestParams.newBuilder().build())
+   *           .build();
+   *   ApiFuture future =
+   *       storageClient.queryWriteStatusCallable().futureCall(request);
+   *   // Do something.
+   *   QueryWriteStatusResponse response = future.get();
+   * }
+   * }
+ */ + public final UnaryCallable + queryWriteStatusCallable() { + return stub.queryWriteStatusCallable(); + } + + @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); + } +} diff --git a/test/integration/goldens/storage/com/google/storage/v2/StorageClientTest.java b/test/integration/goldens/storage/com/google/storage/v2/StorageClientTest.java new file mode 100644 index 0000000000..6374e98e7a --- /dev/null +++ b/test/integration/goldens/storage/com/google/storage/v2/StorageClientTest.java @@ -0,0 +1,301 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.storage.v2; + +import com.google.api.gax.core.NoCredentialsProvider; +import com.google.api.gax.grpc.GaxGrpcProperties; +import com.google.api.gax.grpc.testing.LocalChannelProvider; +import com.google.api.gax.grpc.testing.MockGrpcService; +import com.google.api.gax.grpc.testing.MockServiceHelper; +import com.google.api.gax.grpc.testing.MockStreamObserver; +import com.google.api.gax.rpc.ApiClientHeaderProvider; +import com.google.api.gax.rpc.ApiStreamObserver; +import com.google.api.gax.rpc.ClientStreamingCallable; +import com.google.api.gax.rpc.InvalidArgumentException; +import com.google.api.gax.rpc.ServerStreamingCallable; +import com.google.api.gax.rpc.StatusCode; +import com.google.protobuf.AbstractMessage; +import com.google.protobuf.FieldMask; +import io.grpc.StatusRuntimeException; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.ExecutionException; +import javax.annotation.Generated; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +@Generated("by gapic-generator-java") +public class StorageClientTest { + private static MockServiceHelper mockServiceHelper; + private static MockStorage mockStorage; + private LocalChannelProvider channelProvider; + private StorageClient client; + + @BeforeClass + public static void startStaticServer() { + mockStorage = new MockStorage(); + mockServiceHelper = + new MockServiceHelper( + UUID.randomUUID().toString(), Arrays.asList(mockStorage)); + mockServiceHelper.start(); + } + + @AfterClass + public static void stopServer() { + mockServiceHelper.stop(); + } + + @Before + public void setUp() throws IOException { + mockServiceHelper.reset(); + channelProvider = mockServiceHelper.createChannelProvider(); + StorageSettings settings = + StorageSettings.newBuilder() + .setTransportChannelProvider(channelProvider) + .setCredentialsProvider(NoCredentialsProvider.create()) + .build(); + client = StorageClient.create(settings); + } + + @After + public void tearDown() throws Exception { + client.close(); + } + + @Test + public void readObjectTest() throws Exception { + ReadObjectResponse expectedResponse = + ReadObjectResponse.newBuilder() + .setChecksummedData(ChecksummedData.newBuilder().build()) + .setObjectChecksums(ObjectChecksums.newBuilder().build()) + .setContentRange(ContentRange.newBuilder().build()) + .setMetadata(Object.newBuilder().build()) + .build(); + mockStorage.addResponse(expectedResponse); + ReadObjectRequest request = + ReadObjectRequest.newBuilder() + .setBucket("bucket-1378203158") + .setObject("object-1023368385") + .setGeneration(305703192) + .setReadOffset(-715377828) + .setReadLimit(-164298798) + .setIfGenerationMatch(-1086241088) + .setIfGenerationNotMatch(1475720404) + .setIfMetagenerationMatch(1043427781) + .setIfMetagenerationNotMatch(1025430873) + .setCommonObjectRequestParams(CommonObjectRequestParams.newBuilder().build()) + .setCommonRequestParams(CommonRequestParams.newBuilder().build()) + .setReadMask(FieldMask.newBuilder().build()) + .build(); + + MockStreamObserver responseObserver = new MockStreamObserver<>(); + + ServerStreamingCallable callable = + client.readObjectCallable(); + callable.serverStreamingCall(request, responseObserver); + + List actualResponses = responseObserver.future().get(); + Assert.assertEquals(1, actualResponses.size()); + Assert.assertEquals(expectedResponse, actualResponses.get(0)); + } + + @Test + public void readObjectExceptionTest() throws Exception { + StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); + mockStorage.addException(exception); + ReadObjectRequest request = + ReadObjectRequest.newBuilder() + .setBucket("bucket-1378203158") + .setObject("object-1023368385") + .setGeneration(305703192) + .setReadOffset(-715377828) + .setReadLimit(-164298798) + .setIfGenerationMatch(-1086241088) + .setIfGenerationNotMatch(1475720404) + .setIfMetagenerationMatch(1043427781) + .setIfMetagenerationNotMatch(1025430873) + .setCommonObjectRequestParams(CommonObjectRequestParams.newBuilder().build()) + .setCommonRequestParams(CommonRequestParams.newBuilder().build()) + .setReadMask(FieldMask.newBuilder().build()) + .build(); + + MockStreamObserver responseObserver = new MockStreamObserver<>(); + + ServerStreamingCallable callable = + client.readObjectCallable(); + callable.serverStreamingCall(request, responseObserver); + + try { + List actualResponses = responseObserver.future().get(); + Assert.fail("No exception thrown"); + } catch (ExecutionException e) { + Assert.assertTrue(e.getCause() instanceof InvalidArgumentException); + InvalidArgumentException apiException = ((InvalidArgumentException) e.getCause()); + Assert.assertEquals(StatusCode.Code.INVALID_ARGUMENT, apiException.getStatusCode().getCode()); + } + } + + @Test + public void writeObjectTest() throws Exception { + WriteObjectResponse expectedResponse = WriteObjectResponse.newBuilder().build(); + mockStorage.addResponse(expectedResponse); + WriteObjectRequest request = + WriteObjectRequest.newBuilder() + .setWriteOffset(-1559543565) + .setObjectChecksums(ObjectChecksums.newBuilder().build()) + .setFinishWrite(true) + .setCommonObjectRequestParams(CommonObjectRequestParams.newBuilder().build()) + .setCommonRequestParams(CommonRequestParams.newBuilder().build()) + .build(); + + MockStreamObserver responseObserver = new MockStreamObserver<>(); + + ClientStreamingCallable callable = + client.writeObjectCallable(); + ApiStreamObserver requestObserver = + callable.clientStreamingCall(responseObserver); + + requestObserver.onNext(request); + requestObserver.onCompleted(); + + List actualResponses = responseObserver.future().get(); + Assert.assertEquals(1, actualResponses.size()); + Assert.assertEquals(expectedResponse, actualResponses.get(0)); + } + + @Test + public void writeObjectExceptionTest() throws Exception { + StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); + mockStorage.addException(exception); + WriteObjectRequest request = + WriteObjectRequest.newBuilder() + .setWriteOffset(-1559543565) + .setObjectChecksums(ObjectChecksums.newBuilder().build()) + .setFinishWrite(true) + .setCommonObjectRequestParams(CommonObjectRequestParams.newBuilder().build()) + .setCommonRequestParams(CommonRequestParams.newBuilder().build()) + .build(); + + MockStreamObserver responseObserver = new MockStreamObserver<>(); + + ClientStreamingCallable callable = + client.writeObjectCallable(); + ApiStreamObserver requestObserver = + callable.clientStreamingCall(responseObserver); + + requestObserver.onNext(request); + + try { + List actualResponses = responseObserver.future().get(); + Assert.fail("No exception thrown"); + } catch (ExecutionException e) { + Assert.assertTrue(e.getCause() instanceof InvalidArgumentException); + InvalidArgumentException apiException = ((InvalidArgumentException) e.getCause()); + Assert.assertEquals(StatusCode.Code.INVALID_ARGUMENT, apiException.getStatusCode().getCode()); + } + } + + @Test + public void startResumableWriteTest() throws Exception { + StartResumableWriteResponse expectedResponse = + StartResumableWriteResponse.newBuilder().setUploadId("uploadId1563990780").build(); + mockStorage.addResponse(expectedResponse); + + StartResumableWriteRequest request = + StartResumableWriteRequest.newBuilder() + .setWriteObjectSpec(WriteObjectSpec.newBuilder().build()) + .setCommonObjectRequestParams(CommonObjectRequestParams.newBuilder().build()) + .setCommonRequestParams(CommonRequestParams.newBuilder().build()) + .build(); + + StartResumableWriteResponse actualResponse = client.startResumableWrite(request); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockStorage.getRequests(); + Assert.assertEquals(1, actualRequests.size()); + StartResumableWriteRequest actualRequest = ((StartResumableWriteRequest) actualRequests.get(0)); + + Assert.assertEquals(request.getWriteObjectSpec(), actualRequest.getWriteObjectSpec()); + Assert.assertEquals( + request.getCommonObjectRequestParams(), actualRequest.getCommonObjectRequestParams()); + Assert.assertEquals(request.getCommonRequestParams(), actualRequest.getCommonRequestParams()); + Assert.assertTrue( + channelProvider.isHeaderSent( + ApiClientHeaderProvider.getDefaultApiClientHeaderKey(), + GaxGrpcProperties.getDefaultApiClientHeaderPattern())); + } + + @Test + public void startResumableWriteExceptionTest() throws Exception { + StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); + mockStorage.addException(exception); + + try { + StartResumableWriteRequest request = + StartResumableWriteRequest.newBuilder() + .setWriteObjectSpec(WriteObjectSpec.newBuilder().build()) + .setCommonObjectRequestParams(CommonObjectRequestParams.newBuilder().build()) + .setCommonRequestParams(CommonRequestParams.newBuilder().build()) + .build(); + client.startResumableWrite(request); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } + + @Test + public void queryWriteStatusTest() throws Exception { + QueryWriteStatusResponse expectedResponse = QueryWriteStatusResponse.newBuilder().build(); + mockStorage.addResponse(expectedResponse); + + String uploadId = "uploadId1563990780"; + + QueryWriteStatusResponse actualResponse = client.queryWriteStatus(uploadId); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockStorage.getRequests(); + Assert.assertEquals(1, actualRequests.size()); + QueryWriteStatusRequest actualRequest = ((QueryWriteStatusRequest) actualRequests.get(0)); + + Assert.assertEquals(uploadId, actualRequest.getUploadId()); + Assert.assertTrue( + channelProvider.isHeaderSent( + ApiClientHeaderProvider.getDefaultApiClientHeaderKey(), + GaxGrpcProperties.getDefaultApiClientHeaderPattern())); + } + + @Test + public void queryWriteStatusExceptionTest() throws Exception { + StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); + mockStorage.addException(exception); + + try { + String uploadId = "uploadId1563990780"; + client.queryWriteStatus(uploadId); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } +} diff --git a/test/integration/goldens/storage/com/google/storage/v2/StorageSettings.java b/test/integration/goldens/storage/com/google/storage/v2/StorageSettings.java new file mode 100644 index 0000000000..b675011057 --- /dev/null +++ b/test/integration/goldens/storage/com/google/storage/v2/StorageSettings.java @@ -0,0 +1,219 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.storage.v2; + +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.grpc.InstantiatingGrpcChannelProvider; +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.ServerStreamingCallSettings; +import com.google.api.gax.rpc.StreamingCallSettings; +import com.google.api.gax.rpc.StubSettings; +import com.google.api.gax.rpc.TransportChannelProvider; +import com.google.api.gax.rpc.UnaryCallSettings; +import com.google.storage.v2.stub.StorageStubSettings; +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 StorageClient}. + * + *

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

    + *
  • The default service address (storage.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 startResumableWrite to 30 seconds: + * + *

{@code
+ * StorageSettings.Builder storageSettingsBuilder = StorageSettings.newBuilder();
+ * storageSettingsBuilder
+ *     .startResumableWriteSettings()
+ *     .setRetrySettings(
+ *         storageSettingsBuilder
+ *             .startResumableWriteSettings()
+ *             .getRetrySettings()
+ *             .toBuilder()
+ *             .setTotalTimeout(Duration.ofSeconds(30))
+ *             .build());
+ * StorageSettings storageSettings = storageSettingsBuilder.build();
+ * }
+ */ +@Generated("by gapic-generator-java") +public class StorageSettings extends ClientSettings { + + /** Returns the object with the settings used for calls to readObject. */ + public ServerStreamingCallSettings readObjectSettings() { + return ((StorageStubSettings) getStubSettings()).readObjectSettings(); + } + + /** Returns the object with the settings used for calls to writeObject. */ + public StreamingCallSettings writeObjectSettings() { + return ((StorageStubSettings) getStubSettings()).writeObjectSettings(); + } + + /** Returns the object with the settings used for calls to startResumableWrite. */ + public UnaryCallSettings + startResumableWriteSettings() { + return ((StorageStubSettings) getStubSettings()).startResumableWriteSettings(); + } + + /** Returns the object with the settings used for calls to queryWriteStatus. */ + public UnaryCallSettings + queryWriteStatusSettings() { + return ((StorageStubSettings) getStubSettings()).queryWriteStatusSettings(); + } + + public static final StorageSettings create(StorageStubSettings stub) throws IOException { + return new StorageSettings.Builder(stub.toBuilder()).build(); + } + + /** Returns a builder for the default ExecutorProvider for this service. */ + public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder() { + return StorageStubSettings.defaultExecutorProviderBuilder(); + } + + /** Returns the default service endpoint. */ + public static String getDefaultEndpoint() { + return StorageStubSettings.getDefaultEndpoint(); + } + + /** Returns the default service scopes. */ + public static List getDefaultServiceScopes() { + return StorageStubSettings.getDefaultServiceScopes(); + } + + /** Returns a builder for the default credentials for this service. */ + public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { + return StorageStubSettings.defaultCredentialsProviderBuilder(); + } + + /** Returns a builder for the default ChannelProvider for this service. */ + public static InstantiatingGrpcChannelProvider.Builder defaultGrpcTransportProviderBuilder() { + return StorageStubSettings.defaultGrpcTransportProviderBuilder(); + } + + public static TransportChannelProvider defaultTransportChannelProvider() { + return StorageStubSettings.defaultTransportChannelProvider(); + } + + @BetaApi("The surface for customizing headers is not stable yet and may change in the future.") + public static ApiClientHeaderProvider.Builder defaultApiClientHeaderProviderBuilder() { + return StorageStubSettings.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 StorageSettings(Builder settingsBuilder) throws IOException { + super(settingsBuilder); + } + + /** Builder for StorageSettings. */ + public static class Builder extends ClientSettings.Builder { + + protected Builder() throws IOException { + this(((ClientContext) null)); + } + + protected Builder(ClientContext clientContext) { + super(StorageStubSettings.newBuilder(clientContext)); + } + + protected Builder(StorageSettings settings) { + super(settings.getStubSettings().toBuilder()); + } + + protected Builder(StorageStubSettings.Builder stubSettings) { + super(stubSettings); + } + + private static Builder createDefault() { + return new Builder(StorageStubSettings.newBuilder()); + } + + public StorageStubSettings.Builder getStubSettingsBuilder() { + return ((StorageStubSettings.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 readObject. */ + public ServerStreamingCallSettings.Builder + readObjectSettings() { + return getStubSettingsBuilder().readObjectSettings(); + } + + /** Returns the builder for the settings used for calls to writeObject. */ + public StreamingCallSettings.Builder + writeObjectSettings() { + return getStubSettingsBuilder().writeObjectSettings(); + } + + /** Returns the builder for the settings used for calls to startResumableWrite. */ + public UnaryCallSettings.Builder + startResumableWriteSettings() { + return getStubSettingsBuilder().startResumableWriteSettings(); + } + + /** Returns the builder for the settings used for calls to queryWriteStatus. */ + public UnaryCallSettings.Builder + queryWriteStatusSettings() { + return getStubSettingsBuilder().queryWriteStatusSettings(); + } + + @Override + public StorageSettings build() throws IOException { + return new StorageSettings(this); + } + } +} diff --git a/test/integration/goldens/storage/com/google/storage/v2/gapic_metadata.json b/test/integration/goldens/storage/com/google/storage/v2/gapic_metadata.json new file mode 100644 index 0000000000..a9899e16f9 --- /dev/null +++ b/test/integration/goldens/storage/com/google/storage/v2/gapic_metadata.json @@ -0,0 +1,30 @@ +{ + "schema": "1.0", + "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", + "language": "java", + "protoPackage": "google.storage.v2", + "libraryPackage": "com.google.storage.v2", + "services": { + "Storage": { + "clients": { + "grpc": { + "libraryClient": "StorageClient", + "rpcs": { + "QueryWriteStatus": { + "methods": ["queryWriteStatus", "queryWriteStatus", "queryWriteStatusCallable"] + }, + "ReadObject": { + "methods": ["readObjectCallable"] + }, + "StartResumableWrite": { + "methods": ["startResumableWrite", "startResumableWriteCallable"] + }, + "WriteObject": { + "methods": ["writeObjectCallable"] + } + } + } + } + } + } +} \ No newline at end of file diff --git a/test/integration/goldens/storage/com/google/storage/v2/package-info.java b/test/integration/goldens/storage/com/google/storage/v2/package-info.java new file mode 100644 index 0000000000..bfb389cc80 --- /dev/null +++ b/test/integration/goldens/storage/com/google/storage/v2/package-info.java @@ -0,0 +1,41 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * The interfaces provided are listed below, along with usage samples. + * + *

======================= StorageClient ======================= + * + *

Service Description: Manages Google Cloud Storage resources. + * + *

Sample for StorageClient: + * + *

{@code
+ * try (StorageClient storageClient = StorageClient.create()) {
+ *   StartResumableWriteRequest request =
+ *       StartResumableWriteRequest.newBuilder()
+ *           .setWriteObjectSpec(WriteObjectSpec.newBuilder().build())
+ *           .setCommonObjectRequestParams(CommonObjectRequestParams.newBuilder().build())
+ *           .setCommonRequestParams(CommonRequestParams.newBuilder().build())
+ *           .build();
+ *   StartResumableWriteResponse response = storageClient.startResumableWrite(request);
+ * }
+ * }
+ */ +@Generated("by gapic-generator-java") +package com.google.storage.v2; + +import javax.annotation.Generated; diff --git a/test/integration/goldens/storage/com/google/storage/v2/stub/GrpcStorageCallableFactory.java b/test/integration/goldens/storage/com/google/storage/v2/stub/GrpcStorageCallableFactory.java new file mode 100644 index 0000000000..47ef05368a --- /dev/null +++ b/test/integration/goldens/storage/com/google/storage/v2/stub/GrpcStorageCallableFactory.java @@ -0,0 +1,113 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.storage.v2.stub; + +import com.google.api.gax.grpc.GrpcCallSettings; +import com.google.api.gax.grpc.GrpcCallableFactory; +import com.google.api.gax.grpc.GrpcStubCallableFactory; +import com.google.api.gax.rpc.BatchingCallSettings; +import com.google.api.gax.rpc.BidiStreamingCallable; +import com.google.api.gax.rpc.ClientContext; +import com.google.api.gax.rpc.ClientStreamingCallable; +import com.google.api.gax.rpc.OperationCallSettings; +import com.google.api.gax.rpc.OperationCallable; +import com.google.api.gax.rpc.PagedCallSettings; +import com.google.api.gax.rpc.ServerStreamingCallSettings; +import com.google.api.gax.rpc.ServerStreamingCallable; +import com.google.api.gax.rpc.StreamingCallSettings; +import com.google.api.gax.rpc.UnaryCallSettings; +import com.google.api.gax.rpc.UnaryCallable; +import com.google.longrunning.Operation; +import com.google.longrunning.stub.OperationsStub; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * gRPC callable factory implementation for the Storage service API. + * + *

This class is for advanced usage. + */ +@Generated("by gapic-generator-java") +public class GrpcStorageCallableFactory implements GrpcStubCallableFactory { + + @Override + public UnaryCallable createUnaryCallable( + GrpcCallSettings grpcCallSettings, + UnaryCallSettings callSettings, + ClientContext clientContext) { + return GrpcCallableFactory.createUnaryCallable(grpcCallSettings, callSettings, clientContext); + } + + @Override + public + UnaryCallable createPagedCallable( + GrpcCallSettings grpcCallSettings, + PagedCallSettings callSettings, + ClientContext clientContext) { + return GrpcCallableFactory.createPagedCallable(grpcCallSettings, callSettings, clientContext); + } + + @Override + public UnaryCallable createBatchingCallable( + GrpcCallSettings grpcCallSettings, + BatchingCallSettings callSettings, + ClientContext clientContext) { + return GrpcCallableFactory.createBatchingCallable( + grpcCallSettings, callSettings, clientContext); + } + + @Override + public + OperationCallable createOperationCallable( + GrpcCallSettings grpcCallSettings, + OperationCallSettings callSettings, + ClientContext clientContext, + OperationsStub operationsStub) { + return GrpcCallableFactory.createOperationCallable( + grpcCallSettings, callSettings, clientContext, operationsStub); + } + + @Override + public + BidiStreamingCallable createBidiStreamingCallable( + GrpcCallSettings grpcCallSettings, + StreamingCallSettings callSettings, + ClientContext clientContext) { + return GrpcCallableFactory.createBidiStreamingCallable( + grpcCallSettings, callSettings, clientContext); + } + + @Override + public + ServerStreamingCallable createServerStreamingCallable( + GrpcCallSettings grpcCallSettings, + ServerStreamingCallSettings callSettings, + ClientContext clientContext) { + return GrpcCallableFactory.createServerStreamingCallable( + grpcCallSettings, callSettings, clientContext); + } + + @Override + public + ClientStreamingCallable createClientStreamingCallable( + GrpcCallSettings grpcCallSettings, + StreamingCallSettings callSettings, + ClientContext clientContext) { + return GrpcCallableFactory.createClientStreamingCallable( + grpcCallSettings, callSettings, clientContext); + } +} diff --git a/test/integration/goldens/storage/com/google/storage/v2/stub/GrpcStorageStub.java b/test/integration/goldens/storage/com/google/storage/v2/stub/GrpcStorageStub.java new file mode 100644 index 0000000000..a0ae53ba0e --- /dev/null +++ b/test/integration/goldens/storage/com/google/storage/v2/stub/GrpcStorageStub.java @@ -0,0 +1,231 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.storage.v2.stub; + +import com.google.api.gax.core.BackgroundResource; +import com.google.api.gax.core.BackgroundResourceAggregation; +import com.google.api.gax.grpc.GrpcCallSettings; +import com.google.api.gax.grpc.GrpcStubCallableFactory; +import com.google.api.gax.rpc.ClientContext; +import com.google.api.gax.rpc.ClientStreamingCallable; +import com.google.api.gax.rpc.ServerStreamingCallable; +import com.google.api.gax.rpc.UnaryCallable; +import com.google.longrunning.stub.GrpcOperationsStub; +import com.google.storage.v2.QueryWriteStatusRequest; +import com.google.storage.v2.QueryWriteStatusResponse; +import com.google.storage.v2.ReadObjectRequest; +import com.google.storage.v2.ReadObjectResponse; +import com.google.storage.v2.StartResumableWriteRequest; +import com.google.storage.v2.StartResumableWriteResponse; +import com.google.storage.v2.WriteObjectRequest; +import com.google.storage.v2.WriteObjectResponse; +import io.grpc.MethodDescriptor; +import io.grpc.protobuf.ProtoUtils; +import java.io.IOException; +import java.util.concurrent.TimeUnit; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * gRPC stub implementation for the Storage service API. + * + *

This class is for advanced usage and reflects the underlying API directly. + */ +@Generated("by gapic-generator-java") +public class GrpcStorageStub extends StorageStub { + private static final MethodDescriptor + readObjectMethodDescriptor = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.SERVER_STREAMING) + .setFullMethodName("google.storage.v2.Storage/ReadObject") + .setRequestMarshaller(ProtoUtils.marshaller(ReadObjectRequest.getDefaultInstance())) + .setResponseMarshaller(ProtoUtils.marshaller(ReadObjectResponse.getDefaultInstance())) + .build(); + + private static final MethodDescriptor + writeObjectMethodDescriptor = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.CLIENT_STREAMING) + .setFullMethodName("google.storage.v2.Storage/WriteObject") + .setRequestMarshaller(ProtoUtils.marshaller(WriteObjectRequest.getDefaultInstance())) + .setResponseMarshaller( + ProtoUtils.marshaller(WriteObjectResponse.getDefaultInstance())) + .build(); + + private static final MethodDescriptor + startResumableWriteMethodDescriptor = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.UNARY) + .setFullMethodName("google.storage.v2.Storage/StartResumableWrite") + .setRequestMarshaller( + ProtoUtils.marshaller(StartResumableWriteRequest.getDefaultInstance())) + .setResponseMarshaller( + ProtoUtils.marshaller(StartResumableWriteResponse.getDefaultInstance())) + .build(); + + private static final MethodDescriptor + queryWriteStatusMethodDescriptor = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.UNARY) + .setFullMethodName("google.storage.v2.Storage/QueryWriteStatus") + .setRequestMarshaller( + ProtoUtils.marshaller(QueryWriteStatusRequest.getDefaultInstance())) + .setResponseMarshaller( + ProtoUtils.marshaller(QueryWriteStatusResponse.getDefaultInstance())) + .build(); + + private final ServerStreamingCallable readObjectCallable; + private final ClientStreamingCallable + writeObjectCallable; + private final UnaryCallable + startResumableWriteCallable; + private final UnaryCallable + queryWriteStatusCallable; + + private final BackgroundResource backgroundResources; + private final GrpcOperationsStub operationsStub; + private final GrpcStubCallableFactory callableFactory; + + public static final GrpcStorageStub create(StorageStubSettings settings) throws IOException { + return new GrpcStorageStub(settings, ClientContext.create(settings)); + } + + public static final GrpcStorageStub create(ClientContext clientContext) throws IOException { + return new GrpcStorageStub(StorageStubSettings.newBuilder().build(), clientContext); + } + + public static final GrpcStorageStub create( + ClientContext clientContext, GrpcStubCallableFactory callableFactory) throws IOException { + return new GrpcStorageStub( + StorageStubSettings.newBuilder().build(), clientContext, callableFactory); + } + + /** + * Constructs an instance of GrpcStorageStub, 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 GrpcStorageStub(StorageStubSettings settings, ClientContext clientContext) + throws IOException { + this(settings, clientContext, new GrpcStorageCallableFactory()); + } + + /** + * Constructs an instance of GrpcStorageStub, 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 GrpcStorageStub( + StorageStubSettings settings, + ClientContext clientContext, + GrpcStubCallableFactory callableFactory) + throws IOException { + this.callableFactory = callableFactory; + this.operationsStub = GrpcOperationsStub.create(clientContext, callableFactory); + + GrpcCallSettings readObjectTransportSettings = + GrpcCallSettings.newBuilder() + .setMethodDescriptor(readObjectMethodDescriptor) + .build(); + GrpcCallSettings writeObjectTransportSettings = + GrpcCallSettings.newBuilder() + .setMethodDescriptor(writeObjectMethodDescriptor) + .build(); + GrpcCallSettings + startResumableWriteTransportSettings = + GrpcCallSettings.newBuilder() + .setMethodDescriptor(startResumableWriteMethodDescriptor) + .build(); + GrpcCallSettings + queryWriteStatusTransportSettings = + GrpcCallSettings.newBuilder() + .setMethodDescriptor(queryWriteStatusMethodDescriptor) + .build(); + + this.readObjectCallable = + callableFactory.createServerStreamingCallable( + readObjectTransportSettings, settings.readObjectSettings(), clientContext); + this.writeObjectCallable = + callableFactory.createClientStreamingCallable( + writeObjectTransportSettings, settings.writeObjectSettings(), clientContext); + this.startResumableWriteCallable = + callableFactory.createUnaryCallable( + startResumableWriteTransportSettings, + settings.startResumableWriteSettings(), + clientContext); + this.queryWriteStatusCallable = + callableFactory.createUnaryCallable( + queryWriteStatusTransportSettings, settings.queryWriteStatusSettings(), clientContext); + + this.backgroundResources = + new BackgroundResourceAggregation(clientContext.getBackgroundResources()); + } + + public GrpcOperationsStub getOperationsStub() { + return operationsStub; + } + + @Override + public ServerStreamingCallable readObjectCallable() { + return readObjectCallable; + } + + @Override + public ClientStreamingCallable writeObjectCallable() { + return writeObjectCallable; + } + + @Override + public UnaryCallable + startResumableWriteCallable() { + return startResumableWriteCallable; + } + + @Override + public UnaryCallable + queryWriteStatusCallable() { + return queryWriteStatusCallable; + } + + @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/test/integration/goldens/storage/com/google/storage/v2/stub/StorageStub.java b/test/integration/goldens/storage/com/google/storage/v2/stub/StorageStub.java new file mode 100644 index 0000000000..06ee713906 --- /dev/null +++ b/test/integration/goldens/storage/com/google/storage/v2/stub/StorageStub.java @@ -0,0 +1,62 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.storage.v2.stub; + +import com.google.api.gax.core.BackgroundResource; +import com.google.api.gax.rpc.ClientStreamingCallable; +import com.google.api.gax.rpc.ServerStreamingCallable; +import com.google.api.gax.rpc.UnaryCallable; +import com.google.storage.v2.QueryWriteStatusRequest; +import com.google.storage.v2.QueryWriteStatusResponse; +import com.google.storage.v2.ReadObjectRequest; +import com.google.storage.v2.ReadObjectResponse; +import com.google.storage.v2.StartResumableWriteRequest; +import com.google.storage.v2.StartResumableWriteResponse; +import com.google.storage.v2.WriteObjectRequest; +import com.google.storage.v2.WriteObjectResponse; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * Base stub class for the Storage service API. + * + *

This class is for advanced usage and reflects the underlying API directly. + */ +@Generated("by gapic-generator-java") +public abstract class StorageStub implements BackgroundResource { + + public ServerStreamingCallable readObjectCallable() { + throw new UnsupportedOperationException("Not implemented: readObjectCallable()"); + } + + public ClientStreamingCallable writeObjectCallable() { + throw new UnsupportedOperationException("Not implemented: writeObjectCallable()"); + } + + public UnaryCallable + startResumableWriteCallable() { + throw new UnsupportedOperationException("Not implemented: startResumableWriteCallable()"); + } + + public UnaryCallable + queryWriteStatusCallable() { + throw new UnsupportedOperationException("Not implemented: queryWriteStatusCallable()"); + } + + @Override + public abstract void close(); +} diff --git a/test/integration/goldens/storage/com/google/storage/v2/stub/StorageStubSettings.java b/test/integration/goldens/storage/com/google/storage/v2/stub/StorageStubSettings.java new file mode 100644 index 0000000000..1a505bcd21 --- /dev/null +++ b/test/integration/goldens/storage/com/google/storage/v2/stub/StorageStubSettings.java @@ -0,0 +1,357 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.storage.v2.stub; + +import com.google.api.core.ApiFunction; +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.grpc.GaxGrpcProperties; +import com.google.api.gax.grpc.GrpcTransportChannel; +import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider; +import com.google.api.gax.retrying.RetrySettings; +import com.google.api.gax.rpc.ApiClientHeaderProvider; +import com.google.api.gax.rpc.ClientContext; +import com.google.api.gax.rpc.ServerStreamingCallSettings; +import com.google.api.gax.rpc.StatusCode; +import com.google.api.gax.rpc.StreamingCallSettings; +import com.google.api.gax.rpc.StubSettings; +import com.google.api.gax.rpc.TransportChannelProvider; +import com.google.api.gax.rpc.UnaryCallSettings; +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.storage.v2.QueryWriteStatusRequest; +import com.google.storage.v2.QueryWriteStatusResponse; +import com.google.storage.v2.ReadObjectRequest; +import com.google.storage.v2.ReadObjectResponse; +import com.google.storage.v2.StartResumableWriteRequest; +import com.google.storage.v2.StartResumableWriteResponse; +import com.google.storage.v2.WriteObjectRequest; +import com.google.storage.v2.WriteObjectResponse; +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 StorageStub}. + * + *

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

    + *
  • The default service address (storage.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 startResumableWrite to 30 seconds: + * + *

{@code
+ * StorageStubSettings.Builder storageSettingsBuilder = StorageStubSettings.newBuilder();
+ * storageSettingsBuilder
+ *     .startResumableWriteSettings()
+ *     .setRetrySettings(
+ *         storageSettingsBuilder
+ *             .startResumableWriteSettings()
+ *             .getRetrySettings()
+ *             .toBuilder()
+ *             .setTotalTimeout(Duration.ofSeconds(30))
+ *             .build());
+ * StorageStubSettings storageSettings = storageSettingsBuilder.build();
+ * }
+ */ +@Generated("by gapic-generator-java") +public class StorageStubSettings extends StubSettings { + /** The default scopes of the service. */ + private static final ImmutableList DEFAULT_SERVICE_SCOPES = + ImmutableList.builder() + .add("https://www.googleapis.com/auth/cloud-platform") + .add("https://www.googleapis.com/auth/cloud-platform.read-only") + .add("https://www.googleapis.com/auth/devstorage.full_control") + .add("https://www.googleapis.com/auth/devstorage.read_only") + .add("https://www.googleapis.com/auth/devstorage.read_write") + .build(); + + private final ServerStreamingCallSettings + readObjectSettings; + private final StreamingCallSettings writeObjectSettings; + private final UnaryCallSettings + startResumableWriteSettings; + private final UnaryCallSettings + queryWriteStatusSettings; + + /** Returns the object with the settings used for calls to readObject. */ + public ServerStreamingCallSettings readObjectSettings() { + return readObjectSettings; + } + + /** Returns the object with the settings used for calls to writeObject. */ + public StreamingCallSettings writeObjectSettings() { + return writeObjectSettings; + } + + /** Returns the object with the settings used for calls to startResumableWrite. */ + public UnaryCallSettings + startResumableWriteSettings() { + return startResumableWriteSettings; + } + + /** Returns the object with the settings used for calls to queryWriteStatus. */ + public UnaryCallSettings + queryWriteStatusSettings() { + return queryWriteStatusSettings; + } + + @BetaApi("A restructuring of stub classes is planned, so this may break in the future") + public StorageStub createStub() throws IOException { + if (getTransportChannelProvider() + .getTransportName() + .equals(GrpcTransportChannel.getGrpcTransportName())) { + return GrpcStorageStub.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 "storage.googleapis.com:443"; + } + + /** Returns the default mTLS service endpoint. */ + public static String getDefaultMtlsEndpoint() { + return "storage.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 InstantiatingGrpcChannelProvider.Builder defaultGrpcTransportProviderBuilder() { + return InstantiatingGrpcChannelProvider.newBuilder() + .setMaxInboundMessageSize(Integer.MAX_VALUE); + } + + public static TransportChannelProvider defaultTransportChannelProvider() { + return defaultGrpcTransportProviderBuilder().build(); + } + + @BetaApi("The surface for customizing headers is not stable yet and may change in the future.") + public static ApiClientHeaderProvider.Builder defaultApiClientHeaderProviderBuilder() { + return ApiClientHeaderProvider.newBuilder() + .setGeneratedLibToken("gapic", GaxProperties.getLibraryVersion(StorageStubSettings.class)) + .setTransportToken( + GaxGrpcProperties.getGrpcTokenName(), GaxGrpcProperties.getGrpcVersion()); + } + + /** Returns a new builder for this class. */ + public static Builder newBuilder() { + return Builder.createDefault(); + } + + /** Returns a new builder for this class. */ + public static Builder newBuilder(ClientContext clientContext) { + return new Builder(clientContext); + } + + /** Returns a builder containing all the values of this settings class. */ + public Builder toBuilder() { + return new Builder(this); + } + + protected StorageStubSettings(Builder settingsBuilder) throws IOException { + super(settingsBuilder); + + readObjectSettings = settingsBuilder.readObjectSettings().build(); + writeObjectSettings = settingsBuilder.writeObjectSettings().build(); + startResumableWriteSettings = settingsBuilder.startResumableWriteSettings().build(); + queryWriteStatusSettings = settingsBuilder.queryWriteStatusSettings().build(); + } + + /** Builder for StorageStubSettings. */ + public static class Builder extends StubSettings.Builder { + private final ImmutableList> unaryMethodSettingsBuilders; + private final ServerStreamingCallSettings.Builder + readObjectSettings; + private final StreamingCallSettings.Builder + writeObjectSettings; + private final UnaryCallSettings.Builder + startResumableWriteSettings; + private final UnaryCallSettings.Builder + queryWriteStatusSettings; + 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.DEADLINE_EXCEEDED, 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(1000L)) + .setRetryDelayMultiplier(2.0) + .setMaxRetryDelay(Duration.ofMillis(60000L)) + .setInitialRpcTimeout(Duration.ofMillis(60000L)) + .setRpcTimeoutMultiplier(1.0) + .setMaxRpcTimeout(Duration.ofMillis(60000L)) + .setTotalTimeout(Duration.ofMillis(60000L)) + .build(); + definitions.put("retry_policy_0_params", settings); + RETRY_PARAM_DEFINITIONS = definitions.build(); + } + + protected Builder() { + this(((ClientContext) null)); + } + + protected Builder(ClientContext clientContext) { + super(clientContext); + + readObjectSettings = ServerStreamingCallSettings.newBuilder(); + writeObjectSettings = StreamingCallSettings.newBuilder(); + startResumableWriteSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); + queryWriteStatusSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); + + unaryMethodSettingsBuilders = + ImmutableList.>of( + startResumableWriteSettings, queryWriteStatusSettings); + initDefaults(this); + } + + protected Builder(StorageStubSettings settings) { + super(settings); + + readObjectSettings = settings.readObjectSettings.toBuilder(); + writeObjectSettings = settings.writeObjectSettings.toBuilder(); + startResumableWriteSettings = settings.startResumableWriteSettings.toBuilder(); + queryWriteStatusSettings = settings.queryWriteStatusSettings.toBuilder(); + + unaryMethodSettingsBuilders = + ImmutableList.>of( + startResumableWriteSettings, queryWriteStatusSettings); + } + + 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 + .readObjectSettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("retry_policy_0_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("retry_policy_0_params")); + + builder + .startResumableWriteSettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("retry_policy_0_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("retry_policy_0_params")); + + builder + .queryWriteStatusSettings() + .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 readObject. */ + public ServerStreamingCallSettings.Builder + readObjectSettings() { + return readObjectSettings; + } + + /** Returns the builder for the settings used for calls to writeObject. */ + public StreamingCallSettings.Builder + writeObjectSettings() { + return writeObjectSettings; + } + + /** Returns the builder for the settings used for calls to startResumableWrite. */ + public UnaryCallSettings.Builder + startResumableWriteSettings() { + return startResumableWriteSettings; + } + + /** Returns the builder for the settings used for calls to queryWriteStatus. */ + public UnaryCallSettings.Builder + queryWriteStatusSettings() { + return queryWriteStatusSettings; + } + + @Override + public StorageStubSettings build() throws IOException { + return new StorageStubSettings(this); + } + } +}