diff --git a/.github/release-please.yml b/.github/release-please.yml index 615a27f0bf..1000ca6ad0 100644 --- a/.github/release-please.yml +++ b/.github/release-please.yml @@ -38,3 +38,8 @@ branches: handleGHRelease: true releaseType: java-backport branch: 3.15.x + - bumpMinorPreMajor: true + handleGHRelease: true + releaseType: java-yoshi + branch: protobuf-4.x-rc + manifest: true diff --git a/.github/workflows/hermetic_library_generation.yaml b/.github/workflows/hermetic_library_generation.yaml index 31a38fbb06..8c3df5194a 100644 --- a/.github/workflows/hermetic_library_generation.yaml +++ b/.github/workflows/hermetic_library_generation.yaml @@ -37,7 +37,7 @@ jobs: with: fetch-depth: 0 token: ${{ secrets.CLOUD_JAVA_BOT_TOKEN }} - - uses: googleapis/sdk-platform-java/.github/scripts@v2.64.1 + - uses: googleapis/sdk-platform-java/.github/scripts@v2.64.2 if: env.SHOULD_RUN == 'true' with: base_ref: ${{ github.base_ref }} diff --git a/.github/workflows/unmanaged_dependency_check.yaml b/.github/workflows/unmanaged_dependency_check.yaml index fc7f576f62..3f124637eb 100644 --- a/.github/workflows/unmanaged_dependency_check.yaml +++ b/.github/workflows/unmanaged_dependency_check.yaml @@ -17,6 +17,6 @@ jobs: # repository .kokoro/build.sh - name: Unmanaged dependency check - uses: googleapis/sdk-platform-java/java-shared-dependencies/unmanaged-dependency-check@google-cloud-shared-dependencies/v3.54.1 + uses: googleapis/sdk-platform-java/java-shared-dependencies/unmanaged-dependency-check@google-cloud-shared-dependencies/v3.54.2 with: bom-path: google-cloud-bigquerystorage-bom/pom.xml diff --git a/.kokoro/continuous/graalvm-native-a.cfg b/.kokoro/continuous/graalvm-native-a.cfg index b772eac66c..406018c48a 100644 --- a/.kokoro/continuous/graalvm-native-a.cfg +++ b/.kokoro/continuous/graalvm-native-a.cfg @@ -3,7 +3,7 @@ # Configure the docker image for kokoro-trampoline. env_vars: { key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_a:3.54.1" # {x-version-update:google-cloud-shared-dependencies:current} + value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_a:3.54.2" # {x-version-update:google-cloud-shared-dependencies:current} } env_vars: { diff --git a/.kokoro/continuous/graalvm-native-b.cfg b/.kokoro/continuous/graalvm-native-b.cfg index baf136cf82..60c82d4bf4 100644 --- a/.kokoro/continuous/graalvm-native-b.cfg +++ b/.kokoro/continuous/graalvm-native-b.cfg @@ -3,7 +3,7 @@ # Configure the docker image for kokoro-trampoline. env_vars: { key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_b:3.54.1" # {x-version-update:google-cloud-shared-dependencies:current} + value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_b:3.54.2" # {x-version-update:google-cloud-shared-dependencies:current} } env_vars: { diff --git a/.kokoro/continuous/graalvm-native-c.cfg b/.kokoro/continuous/graalvm-native-c.cfg index 2fb2fc87c4..60982adf5a 100644 --- a/.kokoro/continuous/graalvm-native-c.cfg +++ b/.kokoro/continuous/graalvm-native-c.cfg @@ -3,7 +3,7 @@ # Configure the docker image for kokoro-trampoline. env_vars: { key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_c:3.54.1" # {x-version-update:google-cloud-shared-dependencies:current} + value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_c:3.54.2" # {x-version-update:google-cloud-shared-dependencies:current} } env_vars: { diff --git a/.kokoro/presubmit/graalvm-native-a.cfg b/.kokoro/presubmit/graalvm-native-a.cfg index 0d98de5094..20c0ac4a52 100644 --- a/.kokoro/presubmit/graalvm-native-a.cfg +++ b/.kokoro/presubmit/graalvm-native-a.cfg @@ -3,7 +3,7 @@ # Configure the docker image for kokoro-trampoline. env_vars: { key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_a:3.54.1" + value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_a:3.54.2" } env_vars: { diff --git a/.kokoro/presubmit/graalvm-native-b.cfg b/.kokoro/presubmit/graalvm-native-b.cfg index c270bff717..3b7b14a650 100644 --- a/.kokoro/presubmit/graalvm-native-b.cfg +++ b/.kokoro/presubmit/graalvm-native-b.cfg @@ -3,7 +3,7 @@ # Configure the docker image for kokoro-trampoline. env_vars: { key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_b:3.54.1" + value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_b:3.54.2" } env_vars: { diff --git a/.kokoro/presubmit/graalvm-native-c.cfg b/.kokoro/presubmit/graalvm-native-c.cfg index 720f8bcfaf..a41d88c092 100644 --- a/.kokoro/presubmit/graalvm-native-c.cfg +++ b/.kokoro/presubmit/graalvm-native-c.cfg @@ -3,7 +3,7 @@ # Configure the docker image for kokoro-trampoline. env_vars: { key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_c:3.54.1" + value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_c:3.54.2" } env_vars: { diff --git a/CHANGELOG.md b/CHANGELOG.md index f64defd9d1..4ae63b098f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## [3.19.0](https://github.com/googleapis/java-bigquerystorage/compare/v3.18.0...v3.19.0) (2025-12-12) + + +### Features + +* Add picosecond timestamp support for Json to Proto converter ([#3131](https://github.com/googleapis/java-bigquerystorage/issues/3131)) ([ea1bcc5](https://github.com/googleapis/java-bigquerystorage/commit/ea1bcc509b7c430f92c5764cc4121aaa282255bf)) + + +### Dependencies + +* Update dependency com.google.cloud:sdk-platform-java-config to v3.54.2 ([#3137](https://github.com/googleapis/java-bigquerystorage/issues/3137)) ([2dc42c7](https://github.com/googleapis/java-bigquerystorage/commit/2dc42c7a6a15c4b86f7012a0cd211ca09ffd9a0e)) +* Update googleapis/sdk-platform-java action to v2.64.2 ([#3138](https://github.com/googleapis/java-bigquerystorage/issues/3138)) ([28cbdd9](https://github.com/googleapis/java-bigquerystorage/commit/28cbdd9f5ab36e9d7d0aa8142260dc760e50a3fb)) + ## [3.18.0](https://github.com/googleapis/java-bigquerystorage/compare/v3.17.3...v3.18.0) (2025-11-13) diff --git a/README.md b/README.md index 51ff85e255..50ca189af9 100644 --- a/README.md +++ b/README.md @@ -63,13 +63,13 @@ implementation 'com.google.cloud:google-cloud-bigquerystorage' If you are using Gradle without BOM, add this to your dependencies: ```Groovy -implementation 'com.google.cloud:google-cloud-bigquerystorage:3.18.0' +implementation 'com.google.cloud:google-cloud-bigquerystorage:3.19.0' ``` If you are using SBT, add this to your dependencies: ```Scala -libraryDependencies += "com.google.cloud" % "google-cloud-bigquerystorage" % "3.18.0" +libraryDependencies += "com.google.cloud" % "google-cloud-bigquerystorage" % "3.19.0" ``` ## Authentication @@ -257,7 +257,7 @@ Java is a registered trademark of Oracle and/or its affiliates. [kokoro-badge-link-5]: http://storage.googleapis.com/cloud-devrel-public/java/badges/java-bigquerystorage/java11.html [stability-image]: https://img.shields.io/badge/stability-stable-green [maven-version-image]: https://img.shields.io/maven-central/v/com.google.cloud/google-cloud-bigquerystorage.svg -[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-bigquerystorage/3.18.0 +[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-bigquerystorage/3.19.0 [authentication]: https://github.com/googleapis/google-cloud-java#authentication [auth-scopes]: https://developers.google.com/identity/protocols/oauth2/scopes [predefined-iam-roles]: https://cloud.google.com/iam/docs/understanding-roles#predefined_roles diff --git a/google-cloud-bigquerystorage-bom/pom.xml b/google-cloud-bigquerystorage-bom/pom.xml index 0ad7de64cd..fc22de0e34 100644 --- a/google-cloud-bigquerystorage-bom/pom.xml +++ b/google-cloud-bigquerystorage-bom/pom.xml @@ -3,12 +3,12 @@ 4.0.0 com.google.cloud google-cloud-bigquerystorage-bom - 3.18.1-rc1-SNAPSHOT + 3.19.1-SNAPSHOT pom com.google.cloud sdk-platform-java-config - 3.54.1 + 3.54.2 Google Cloud bigquerystorage BOM @@ -52,57 +52,57 @@ com.google.cloud google-cloud-bigquerystorage - 3.18.1-rc1-SNAPSHOT + 3.19.1-SNAPSHOT com.google.api.grpc grpc-google-cloud-bigquerystorage-v1beta1 - 0.190.1-rc1-SNAPSHOT + 0.191.1-SNAPSHOT com.google.api.grpc grpc-google-cloud-bigquerystorage-v1beta2 - 0.190.1-rc1-SNAPSHOT + 0.191.1-SNAPSHOT com.google.api.grpc grpc-google-cloud-bigquerystorage-v1 - 3.18.1-rc1-SNAPSHOT + 3.19.1-SNAPSHOT com.google.api.grpc grpc-google-cloud-bigquerystorage-v1alpha - 3.18.1-rc1-SNAPSHOT + 3.19.1-SNAPSHOT com.google.api.grpc grpc-google-cloud-bigquerystorage-v1beta - 3.18.1-rc1-SNAPSHOT + 3.19.1-SNAPSHOT com.google.api.grpc proto-google-cloud-bigquerystorage-v1beta1 - 0.190.1-rc1-SNAPSHOT + 0.191.1-SNAPSHOT com.google.api.grpc proto-google-cloud-bigquerystorage-v1beta2 - 0.190.1-rc1-SNAPSHOT + 0.191.1-SNAPSHOT com.google.api.grpc proto-google-cloud-bigquerystorage-v1 - 3.18.1-rc1-SNAPSHOT + 3.19.1-SNAPSHOT com.google.api.grpc proto-google-cloud-bigquerystorage-v1alpha - 3.18.1-rc1-SNAPSHOT + 3.19.1-SNAPSHOT com.google.api.grpc proto-google-cloud-bigquerystorage-v1beta - 3.18.1-rc1-SNAPSHOT + 3.19.1-SNAPSHOT diff --git a/google-cloud-bigquerystorage/pom.xml b/google-cloud-bigquerystorage/pom.xml index 0f23a2e8de..581129ad59 100644 --- a/google-cloud-bigquerystorage/pom.xml +++ b/google-cloud-bigquerystorage/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.cloud google-cloud-bigquerystorage - 3.18.1-rc1-SNAPSHOT + 3.19.1-SNAPSHOT jar BigQuery Storage https://github.com/googleapis/java-bigquerystorage @@ -11,7 +11,7 @@ com.google.cloud google-cloud-bigquerystorage-parent - 3.18.1-rc1-SNAPSHOT + 3.19.1-SNAPSHOT google-cloud-bigquerystorage diff --git a/google-cloud-bigquerystorage/src/main/java/com/google/cloud/bigquery/storage/v1/BQTableSchemaToProtoDescriptor.java b/google-cloud-bigquerystorage/src/main/java/com/google/cloud/bigquery/storage/v1/BQTableSchemaToProtoDescriptor.java index 60bb739b23..5842f6d068 100644 --- a/google-cloud-bigquerystorage/src/main/java/com/google/cloud/bigquery/storage/v1/BQTableSchemaToProtoDescriptor.java +++ b/google-cloud-bigquerystorage/src/main/java/com/google/cloud/bigquery/storage/v1/BQTableSchemaToProtoDescriptor.java @@ -30,6 +30,8 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.logging.Logger; /** * Converts a BQ table schema to protobuf descriptor. All field names will be converted to lowercase @@ -37,15 +39,18 @@ * shown in the ImmutableMaps below. */ public class BQTableSchemaToProtoDescriptor { - private static ImmutableMap - BQTableSchemaModeMap = - ImmutableMap.of( - TableFieldSchema.Mode.NULLABLE, FieldDescriptorProto.Label.LABEL_OPTIONAL, - TableFieldSchema.Mode.REPEATED, FieldDescriptorProto.Label.LABEL_REPEATED, - TableFieldSchema.Mode.REQUIRED, FieldDescriptorProto.Label.LABEL_REQUIRED); - private static ImmutableMap - BQTableSchemaTypeMap = + private static final Logger LOG = + Logger.getLogger(BQTableSchemaToProtoDescriptor.class.getName()); + + private static Map DEFAULT_BQ_TABLE_SCHEMA_MODE_MAP = + ImmutableMap.of( + TableFieldSchema.Mode.NULLABLE, FieldDescriptorProto.Label.LABEL_OPTIONAL, + TableFieldSchema.Mode.REPEATED, FieldDescriptorProto.Label.LABEL_REPEATED, + TableFieldSchema.Mode.REQUIRED, FieldDescriptorProto.Label.LABEL_REQUIRED); + + private static Map + DEFAULT_BQ_TABLE_SCHEMA_TYPE_MAP = new ImmutableMap.Builder() .put(TableFieldSchema.Type.BOOL, FieldDescriptorProto.Type.TYPE_BOOL) .put(TableFieldSchema.Type.BYTES, FieldDescriptorProto.Type.TYPE_BYTES) @@ -142,11 +147,13 @@ private static Descriptor convertBQTableSchemaToProtoDescriptorImpl( .setType(BQTableField.getRangeElementType().getType()) .setName("start") .setMode(Mode.NULLABLE) + .setTimestampPrecision(BQTableField.getTimestampPrecision()) .build(), TableFieldSchema.newBuilder() .setType(BQTableField.getRangeElementType().getType()) .setName("end") .setMode(Mode.NULLABLE) + .setTimestampPrecision(BQTableField.getTimestampPrecision()) .build()); if (dependencyMap.containsKey(rangeFields)) { @@ -189,7 +196,7 @@ private static Descriptor convertBQTableSchemaToProtoDescriptorImpl( * @param index Index for protobuf fields. * @param scope used to name descriptors */ - private static FieldDescriptorProto convertBQTableFieldToProtoField( + static FieldDescriptorProto convertBQTableFieldToProtoField( TableFieldSchema BQTableField, int index, String scope) { TableFieldSchema.Mode mode = BQTableField.getMode(); String fieldName = BQTableField.getName().toLowerCase(); @@ -198,7 +205,7 @@ private static FieldDescriptorProto convertBQTableFieldToProtoField( FieldDescriptorProto.newBuilder() .setName(fieldName) .setNumber(index) - .setLabel((FieldDescriptorProto.Label) BQTableSchemaModeMap.get(mode)); + .setLabel((FieldDescriptorProto.Label) DEFAULT_BQ_TABLE_SCHEMA_MODE_MAP.get(mode)); switch (BQTableField.getType()) { case STRUCT: @@ -206,12 +213,37 @@ private static FieldDescriptorProto convertBQTableFieldToProtoField( break; case RANGE: fieldDescriptor.setType( - (FieldDescriptorProto.Type) BQTableSchemaTypeMap.get(BQTableField.getType())); + (FieldDescriptorProto.Type) + DEFAULT_BQ_TABLE_SCHEMA_TYPE_MAP.get(BQTableField.getType())); fieldDescriptor.setTypeName(scope); break; + case TIMESTAMP: + // Can map to either int64 or string based on the BQ Field's timestamp precision + // Default: microsecond (6) maps to int64 and picosecond (12) maps to string. + long timestampPrecision = BQTableField.getTimestampPrecision().getValue(); + if (timestampPrecision == 12L) { + fieldDescriptor.setType( + (FieldDescriptorProto.Type) FieldDescriptorProto.Type.TYPE_STRING); + break; + } + // This should never happen as this is a server response issue. If this is the case, + // warn the user and use INT64 as the default is microsecond precision. + if (timestampPrecision != 6L && timestampPrecision != 0L) { + LOG.warning( + "BigQuery Timestamp field " + + BQTableField.getName() + + " has timestamp precision that is not 6 or 12. Defaulting to microsecond" + + " precision and mapping to INT64 protobuf type."); + } + // If the timestampPrecision value comes back as a null result from the server, + // timestampPrecision has a value of 0L. Use the INT64 to map to the type used + // for the default precision (microsecond). + fieldDescriptor.setType((FieldDescriptorProto.Type) FieldDescriptorProto.Type.TYPE_INT64); + break; default: fieldDescriptor.setType( - (FieldDescriptorProto.Type) BQTableSchemaTypeMap.get(BQTableField.getType())); + (FieldDescriptorProto.Type) + DEFAULT_BQ_TABLE_SCHEMA_TYPE_MAP.get(BQTableField.getType())); break; } diff --git a/google-cloud-bigquerystorage/src/main/java/com/google/cloud/bigquery/storage/v1/JsonToProtoMessage.java b/google-cloud-bigquerystorage/src/main/java/com/google/cloud/bigquery/storage/v1/JsonToProtoMessage.java index 9a4fecf780..6e5643f002 100644 --- a/google-cloud-bigquerystorage/src/main/java/com/google/cloud/bigquery/storage/v1/JsonToProtoMessage.java +++ b/google-cloud-bigquerystorage/src/main/java/com/google/cloud/bigquery/storage/v1/JsonToProtoMessage.java @@ -15,8 +15,14 @@ */ package com.google.cloud.bigquery.storage.v1; +import static java.time.temporal.ChronoField.HOUR_OF_DAY; +import static java.time.temporal.ChronoField.MINUTE_OF_HOUR; +import static java.time.temporal.ChronoField.NANO_OF_SECOND; +import static java.time.temporal.ChronoField.SECOND_OF_MINUTE; + import com.google.api.pathtemplate.ValidationException; import com.google.cloud.bigquery.storage.v1.Exceptions.RowIndexToErrorException; +import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableMap; import com.google.common.primitives.Doubles; @@ -26,15 +32,18 @@ import com.google.protobuf.Descriptors.Descriptor; import com.google.protobuf.Descriptors.FieldDescriptor; import com.google.protobuf.DynamicMessage; +import com.google.protobuf.Timestamp; import com.google.protobuf.UninitializedMessageException; import java.math.BigDecimal; import java.math.RoundingMode; +import java.time.Instant; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatterBuilder; +import java.time.format.DateTimeParseException; import java.time.format.TextStyle; import java.time.temporal.ChronoField; import java.time.temporal.TemporalAccessor; @@ -42,6 +51,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -63,7 +74,31 @@ public class JsonToProtoMessage implements ToProtoConverter { .put(FieldDescriptor.Type.STRING, "string") .put(FieldDescriptor.Type.MESSAGE, "object") .build(); - private static final DateTimeFormatter TIMESTAMP_FORMATTER = + + private static final DateTimeFormatter TO_TIMESTAMP_FORMATTER = + new DateTimeFormatterBuilder() + .parseLenient() + .append(DateTimeFormatter.ISO_LOCAL_DATE) + .optionalStart() + .appendLiteral('T') + .optionalEnd() + .appendValue(HOUR_OF_DAY, 2) + .appendLiteral(':') + .appendValue(MINUTE_OF_HOUR, 2) + .optionalStart() + .appendLiteral(':') + .appendValue(SECOND_OF_MINUTE, 2) + .optionalEnd() + .optionalStart() + .appendFraction(NANO_OF_SECOND, 6, 9, true) + .optionalEnd() + .optionalStart() + .appendOffset("+HHMM", "+00:00") + .optionalEnd() + .toFormatter() + .withZone(ZoneOffset.UTC); + + private static final DateTimeFormatter FROM_TIMESTAMP_FORMATTER = new DateTimeFormatterBuilder() .parseLenient() .append(DateTimeFormatter.ofPattern("yyyy[/][-]MM[/][-]dd")) @@ -120,6 +155,14 @@ public class JsonToProtoMessage implements ToProtoConverter { .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0) .toFormatter(); + // Regex to identify >9 digits in the fraction part (e.g. `.123456789123`) + // Matches the dot, followed by 10+ digits (fractional part), followed by non-digits (like `+00`) + // or end of string + private static final Pattern ISO8601_TIMESTAMP_HIGH_PRECISION_PATTERN = + Pattern.compile("\\.(\\d{10,})(?:\\D|$)"); + private static final long MICROS_PER_SECOND = 1_000_000; + private static final int NANOS_PER_MICRO = 1_000; + /** You can use {@link #INSTANCE} instead */ public JsonToProtoMessage() {} @@ -620,25 +663,8 @@ private void fillField( return; } } else if (fieldSchema.getType() == TableFieldSchema.Type.TIMESTAMP) { - if (val instanceof String) { - Double parsed = Doubles.tryParse((String) val); - if (parsed != null) { - protoMsg.setField(fieldDescriptor, parsed.longValue()); - return; - } - TemporalAccessor parsedTime = TIMESTAMP_FORMATTER.parse((String) val); - protoMsg.setField( - fieldDescriptor, - parsedTime.getLong(ChronoField.INSTANT_SECONDS) * 1000000 - + parsedTime.getLong(ChronoField.MICRO_OF_SECOND)); - return; - } else if (val instanceof Long) { - protoMsg.setField(fieldDescriptor, val); - return; - } else if (val instanceof Integer) { - protoMsg.setField(fieldDescriptor, Long.valueOf((Integer) val)); - return; - } + protoMsg.setField(fieldDescriptor, getTimestampAsLong(val)); + return; } } if (val instanceof Integer) { @@ -685,6 +711,14 @@ private void fillField( } break; case STRING: + // Timestamp fields will be transmitted as a String if BQ's timestamp field is + // enabled to support picosecond. Check that the schema's field is timestamp before + // proceeding with the rest of the logic. Converts the supported types into a String. + // Supported types: https://docs.cloud.google.com/bigquery/docs/supported-data-types + if (fieldSchema != null && fieldSchema.getType() == TableFieldSchema.Type.TIMESTAMP) { + protoMsg.setField(fieldDescriptor, getTimestampAsString(val)); + return; + } if (val instanceof String) { protoMsg.setField(fieldDescriptor, val); return; @@ -897,24 +931,7 @@ private void fillRepeatedField( } } else if (fieldSchema != null && fieldSchema.getType() == TableFieldSchema.Type.TIMESTAMP) { - if (val instanceof String) { - Double parsed = Doubles.tryParse((String) val); - if (parsed != null) { - protoMsg.addRepeatedField(fieldDescriptor, parsed.longValue()); - } else { - TemporalAccessor parsedTime = TIMESTAMP_FORMATTER.parse((String) val); - protoMsg.addRepeatedField( - fieldDescriptor, - parsedTime.getLong(ChronoField.INSTANT_SECONDS) * 1000000 - + parsedTime.getLong(ChronoField.MICRO_OF_SECOND)); - } - } else if (val instanceof Long) { - protoMsg.addRepeatedField(fieldDescriptor, val); - } else if (val instanceof Integer) { - protoMsg.addRepeatedField(fieldDescriptor, Long.valueOf((Integer) val)); - } else { - throwWrongFieldType(fieldDescriptor, currentScope, index); - } + protoMsg.addRepeatedField(fieldDescriptor, getTimestampAsLong(val)); } else if (val instanceof Integer) { protoMsg.addRepeatedField(fieldDescriptor, Long.valueOf((Integer) val)); } else if (val instanceof Long) { @@ -958,6 +975,14 @@ private void fillRepeatedField( } break; case STRING: + // Timestamp fields will be transmitted as a String if BQ's timestamp field is + // enabled to support picosecond. Check that the schema's field is timestamp before + // proceeding with the rest of the logic. Converts the supported types into a String. + // Supported types: https://docs.cloud.google.com/bigquery/docs/supported-data-types + if (fieldSchema != null && fieldSchema.getType() == TableFieldSchema.Type.TIMESTAMP) { + protoMsg.addRepeatedField(fieldDescriptor, getTimestampAsString(val)); + return; + } if (val instanceof String) { protoMsg.addRepeatedField(fieldDescriptor, val); } else if (val instanceof Short @@ -1002,6 +1027,76 @@ private void fillRepeatedField( } } + /** + * Converts microseconds from epoch to a Java Instant. + * + * @param micros the number of microseconds from 1970-01-01T00:00:00Z + * @return the Instant corresponding to the microseconds + */ + @VisibleForTesting + static Instant fromEpochMicros(long micros) { + long seconds = Math.floorDiv(micros, MICROS_PER_SECOND); + int nanos = (int) Math.floorMod(micros, MICROS_PER_SECOND) * NANOS_PER_MICRO; + + return Instant.ofEpochSecond(seconds, nanos); + } + + /** + * Best effort to try and convert a timestamp to an ISO8601 string. Standardize the timestamp + * output to be ISO_DATE_TIME (e.g. 2011-12-03T10:15:30+01:00) for timestamps up to nanosecond + * precision. For higher precision, the ISO8601 input is used as long as it is valid. + */ + @VisibleForTesting + static String getTimestampAsString(Object val) { + if (val instanceof String) { + String value = (String) val; + Double parsed = Doubles.tryParse(value); + // If true, it was a numeric value inside a String + if (parsed != null) { + return getTimestampAsString(parsed.longValue()); + } + // Validate the ISO8601 values before sending it to the server. + validateTimestamp(value); + + // If it's high precision (more than 9 digits), then return the ISO8601 string as-is + // as JDK does not have a DateTimeFormatter that supports more than nanosecond precision. + Matcher matcher = ISO8601_TIMESTAMP_HIGH_PRECISION_PATTERN.matcher(value); + if (matcher.find()) { + return value; + } + // Otherwise, output the timestamp to a standard format before sending it to BQ + Instant instant = FROM_TIMESTAMP_FORMATTER.parse(value, Instant::from); + return TO_TIMESTAMP_FORMATTER.format(instant); + } else if (val instanceof Number) { + // Micros from epoch will most likely will be represented a Long, but any numeric + // value can be used + Instant instant = fromEpochMicros(((Number) val).longValue()); + return TO_TIMESTAMP_FORMATTER.format(instant); + } else if (val instanceof Timestamp) { + // Convert the Protobuf timestamp class to ISO8601 string + Timestamp timestamp = (Timestamp) val; + return TO_TIMESTAMP_FORMATTER.format( + Instant.ofEpochSecond(timestamp.getSeconds(), timestamp.getNanos())); + } + throw new IllegalArgumentException("The timestamp value passed in is not from a valid type"); + } + + /* Best effort to try and convert the Object to a long (microseconds since epoch) */ + private long getTimestampAsLong(Object val) { + if (val instanceof String) { + Double parsed = Doubles.tryParse((String) val); + if (parsed != null) { + return parsed.longValue(); + } + TemporalAccessor parsedTime = FROM_TIMESTAMP_FORMATTER.parse((String) val); + return parsedTime.getLong(ChronoField.INSTANT_SECONDS) * 1000000 + + parsedTime.getLong(ChronoField.MICRO_OF_SECOND); + } else if (val instanceof Number) { + return ((Number) val).longValue(); + } + throw new IllegalArgumentException("The timestamp value passed in is not from a valid type"); + } + private static void throwWrongFieldType( FieldDescriptor fieldDescriptor, String currentScope, int index) { throw new IllegalArgumentException( @@ -1009,4 +1104,43 @@ private static void throwWrongFieldType( "JSONObject does not have a %s field at %s[%d].", FIELD_TYPE_TO_DEBUG_MESSAGE.get(fieldDescriptor.getType()), currentScope, index)); } + + /** + * Internal helper method to check that the timestamp follows the expected String input of ISO8601 + * string. Allows the fractional portion of the timestamp to support up to 12 digits of precision + * (up to picosecond). + * + * @throws IllegalArgumentException if timestamp is invalid or exceeds picosecond precision + */ + @VisibleForTesting + static void validateTimestamp(String timestamp) { + // Check if the string has greater than nanosecond precision (>9 digits in fractional second) + Matcher matcher = ISO8601_TIMESTAMP_HIGH_PRECISION_PATTERN.matcher(timestamp); + if (matcher.find()) { + // Group 1 is the fractional second part of the ISO8601 string + String fraction = matcher.group(1); + // Pos 10-12 of the fractional second are guaranteed to be digits. The regex only + // matches the fraction section as long as they are digits. + if (fraction.length() > 12) { + throw new IllegalArgumentException( + "Fractional second portion of ISO8601 only supports up to picosecond (12 digits) in" + + " BigQuery"); + } + + // Replace the entire fractional second portion with just the nanosecond portion. + // The new timestamp will be validated against the JDK's DateTimeFormatter + String truncatedFraction = fraction.substring(0, 9); + timestamp = + new StringBuilder(timestamp) + .replace(matcher.start(1), matcher.end(1), truncatedFraction) + .toString(); + } + + // It is valid as long as DateTimeFormatter doesn't throw an exception + try { + FROM_TIMESTAMP_FORMATTER.parse((String) timestamp); + } catch (DateTimeParseException e) { + throw new IllegalArgumentException(e.getMessage(), e); + } + } } diff --git a/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/BQTableSchemaToProtoDescriptorTest.java b/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/BQTableSchemaToProtoDescriptorTest.java index ba845c1c12..51b78df183 100644 --- a/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/BQTableSchemaToProtoDescriptorTest.java +++ b/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/BQTableSchemaToProtoDescriptorTest.java @@ -15,13 +15,18 @@ */ package com.google.cloud.bigquery.storage.v1; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; -import com.google.cloud.bigquery.storage.test.JsonTest.*; -import com.google.cloud.bigquery.storage.test.SchemaTest.*; +import com.google.cloud.bigquery.storage.test.JsonTest; +import com.google.cloud.bigquery.storage.test.SchemaTest; import com.google.common.collect.ImmutableMap; +import com.google.protobuf.DescriptorProtos; +import com.google.protobuf.Descriptors; import com.google.protobuf.Descriptors.Descriptor; import com.google.protobuf.Descriptors.FieldDescriptor; +import com.google.protobuf.Int64Value; import java.util.HashMap; import java.util.Map; import org.junit.Test; @@ -32,21 +37,20 @@ public class BQTableSchemaToProtoDescriptorTest { // This is a map between the TableFieldSchema.Type and the descriptor it is supposed to // produce. The produced descriptor will be used to check against the entry values here. - private static ImmutableMap - BQTableTypeToCorrectProtoDescriptorTest = - new ImmutableMap.Builder() - .put(TableFieldSchema.Type.BOOL, BoolType.getDescriptor()) - .put(TableFieldSchema.Type.BYTES, BytesType.getDescriptor()) - .put(TableFieldSchema.Type.DATE, Int32Type.getDescriptor()) - .put(TableFieldSchema.Type.DATETIME, Int64Type.getDescriptor()) - .put(TableFieldSchema.Type.DOUBLE, DoubleType.getDescriptor()) - .put(TableFieldSchema.Type.GEOGRAPHY, StringType.getDescriptor()) - .put(TableFieldSchema.Type.INT64, Int64Type.getDescriptor()) - .put(TableFieldSchema.Type.NUMERIC, BytesType.getDescriptor()) - .put(TableFieldSchema.Type.STRING, StringType.getDescriptor()) - .put(TableFieldSchema.Type.TIME, Int64Type.getDescriptor()) - .put(TableFieldSchema.Type.TIMESTAMP, Int64Type.getDescriptor()) - .build(); + private static Map BQTableTypeToCorrectProtoDescriptorTest = + new ImmutableMap.Builder() + .put(TableFieldSchema.Type.BOOL, SchemaTest.BoolType.getDescriptor()) + .put(TableFieldSchema.Type.BYTES, SchemaTest.BytesType.getDescriptor()) + .put(TableFieldSchema.Type.DATE, SchemaTest.Int32Type.getDescriptor()) + .put(TableFieldSchema.Type.DATETIME, SchemaTest.Int64Type.getDescriptor()) + .put(TableFieldSchema.Type.DOUBLE, SchemaTest.DoubleType.getDescriptor()) + .put(TableFieldSchema.Type.GEOGRAPHY, SchemaTest.StringType.getDescriptor()) + .put(TableFieldSchema.Type.INT64, SchemaTest.Int64Type.getDescriptor()) + .put(TableFieldSchema.Type.NUMERIC, SchemaTest.BytesType.getDescriptor()) + .put(TableFieldSchema.Type.STRING, SchemaTest.StringType.getDescriptor()) + .put(TableFieldSchema.Type.TIME, SchemaTest.Int64Type.getDescriptor()) + .put(TableFieldSchema.Type.TIMESTAMP, SchemaTest.Int64Type.getDescriptor()) + .build(); // Creates mapping from descriptor to how many times it was reused. private void mapDescriptorToCount(Descriptor descriptor, HashMap map) { @@ -64,25 +68,28 @@ private void mapDescriptorToCount(Descriptor descriptor, HashMap JsonToProtoMessage.getTimestampAsString("2025-10-01")); + assertThrows( + IllegalArgumentException.class, () -> JsonToProtoMessage.getTimestampAsString("abc")); + assertThrows( + IllegalArgumentException.class, + () -> JsonToProtoMessage.getTimestampAsString(Timestamp.newBuilder())); + assertThrows( + IllegalArgumentException.class, + () -> JsonToProtoMessage.getTimestampAsString(new Object())); + assertThrows( + IllegalArgumentException.class, () -> JsonToProtoMessage.getTimestampAsString(null)); + } + + @Test + public void testFromEpochMicros() { + // The `+` is added if there are more than 4 digits for years + assertEquals( + "+294247-01-10T04:00:54.775807Z", + JsonToProtoMessage.fromEpochMicros(Long.MAX_VALUE).toString()); + assertEquals( + "-290308-12-21T19:59:05.224192Z", + JsonToProtoMessage.fromEpochMicros(Long.MIN_VALUE).toString()); + assertEquals(Instant.EPOCH.toString(), JsonToProtoMessage.fromEpochMicros(0L).toString()); + } } diff --git a/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/StreamWriterTest.java b/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/StreamWriterTest.java index 200babf5a8..cbf61e8fff 100644 --- a/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/StreamWriterTest.java +++ b/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/StreamWriterTest.java @@ -189,9 +189,11 @@ public void setUp() throws Exception { @After public void tearDown() throws Exception { log.info("tearDown called"); - client.close(); serviceHelper.stop(); StreamWriter.cleanUp(); + + client.close(); + client.awaitTermination(10, TimeUnit.SECONDS); } private StreamWriter getMultiplexingTestStreamWriter() throws IOException { @@ -1996,6 +1998,9 @@ public void testBuilderExplicitSetting() throws Exception { ((GoogleCredentialsProvider) writerSettings2.getCredentialsProvider()) .getScopesToApply() .size()); + + client.close(); + client.awaitTermination(10, TimeUnit.SECONDS); } @Test diff --git a/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/it/ITBigQueryBigDecimalByteStringEncoderTest.java b/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/it/ITBigQueryBigDecimalByteStringEncoderTest.java index cd2195d066..46aedb159a 100644 --- a/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/it/ITBigQueryBigDecimalByteStringEncoderTest.java +++ b/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/it/ITBigQueryBigDecimalByteStringEncoderTest.java @@ -44,6 +44,7 @@ import java.math.BigDecimal; import java.util.Iterator; import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; import java.util.logging.Logger; import org.json.JSONArray; import org.json.JSONObject; @@ -91,9 +92,10 @@ public static void beforeClass() throws IOException { } @AfterClass - public static void afterClass() { + public static void afterClass() throws InterruptedException { if (client != null) { client.close(); + client.awaitTermination(10, TimeUnit.SECONDS); } if (bigquery != null) { RemoteBigQueryHelper.forceDelete(bigquery, DATASET); diff --git a/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/it/ITBigQueryStorageLongRunningTest.java b/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/it/ITBigQueryStorageLongRunningTest.java index 9ca508bac4..54127076b1 100644 --- a/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/it/ITBigQueryStorageLongRunningTest.java +++ b/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/it/ITBigQueryStorageLongRunningTest.java @@ -34,6 +34,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; import java.util.logging.Logger; import org.junit.AfterClass; import org.junit.Assume; @@ -74,9 +75,10 @@ public static void beforeClass() throws IOException { } @AfterClass - public static void afterClass() { + public static void afterClass() throws InterruptedException { if (client != null) { client.close(); + client.awaitTermination(10, TimeUnit.SECONDS); } } diff --git a/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/it/ITBigQueryStorageTest.java b/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/it/ITBigQueryStorageTest.java index a8f7b0b8bc..6e502d9745 100644 --- a/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/it/ITBigQueryStorageTest.java +++ b/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/it/ITBigQueryStorageTest.java @@ -104,6 +104,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.concurrent.TimeUnit; import java.util.logging.Logger; import org.apache.avro.Conversions; import org.apache.avro.LogicalTypes; @@ -516,9 +517,10 @@ public static void beforeClass() throws IOException { } @AfterClass - public static void afterClass() { + public static void afterClass() throws InterruptedException { if (client != null) { client.close(); + client.awaitTermination(10, TimeUnit.SECONDS); } if (bigquery != null) { @@ -1436,7 +1438,8 @@ public void testStructAndArraySqlTypes() throws InterruptedException, IOExceptio } @Test - public void testSimpleReadWithBackgroundExecutorProvider() throws IOException { + public void testSimpleReadWithBackgroundExecutorProvider() + throws IOException, InterruptedException { BigQueryReadSettings bigQueryReadSettings = BigQueryReadSettings.newBuilder() .setBackgroundExecutorProvider( diff --git a/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/it/ITBigQueryTimeEncoderTest.java b/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/it/ITBigQueryTimeEncoderTest.java index a653143ed8..d58171003b 100644 --- a/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/it/ITBigQueryTimeEncoderTest.java +++ b/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/it/ITBigQueryTimeEncoderTest.java @@ -44,6 +44,7 @@ import java.time.LocalTime; import java.util.Iterator; import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; import org.json.JSONArray; import org.json.JSONObject; import org.junit.AfterClass; @@ -98,9 +99,10 @@ public static void beforeClass() throws IOException { } @AfterClass - public static void afterClass() { + public static void afterClass() throws InterruptedException { if (client != null) { client.close(); + client.awaitTermination(10, TimeUnit.SECONDS); } if (bigquery != null) { RemoteBigQueryHelper.forceDelete(bigquery, DATASET); diff --git a/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/it/ITBigQueryWriteManualClientTest.java b/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/it/ITBigQueryWriteManualClientTest.java index 756dfcc793..20e5b80267 100644 --- a/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/it/ITBigQueryWriteManualClientTest.java +++ b/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/it/ITBigQueryWriteManualClientTest.java @@ -216,9 +216,10 @@ public static void beforeClass() throws IOException { } @AfterClass - public static void afterClass() { + public static void afterClass() throws InterruptedException { if (client != null) { client.close(); + client.awaitTermination(10, TimeUnit.SECONDS); } if (bigquery != null) { diff --git a/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/stub/ResourceHeaderTest.java b/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/stub/ResourceHeaderTest.java index a68f6e3ae5..e12e92bd19 100644 --- a/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/stub/ResourceHeaderTest.java +++ b/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/stub/ResourceHeaderTest.java @@ -28,6 +28,7 @@ import com.google.cloud.bigquery.storage.v1.ReadRowsRequest; import com.google.cloud.bigquery.storage.v1.ReadSession; import com.google.cloud.bigquery.storage.v1.SplitReadStreamRequest; +import java.util.concurrent.TimeUnit; import java.util.regex.Pattern; import org.junit.After; import org.junit.AfterClass; @@ -88,6 +89,7 @@ public void setUp() throws Exception { @After public void tearDown() throws Exception { client.close(); + client.awaitTermination(10, TimeUnit.SECONDS); } @AfterClass diff --git a/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/stub/readrows/ReadRowsRetryTest.java b/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/stub/readrows/ReadRowsRetryTest.java index 2a2e513bec..92a8b79cf1 100644 --- a/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/stub/readrows/ReadRowsRetryTest.java +++ b/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/stub/readrows/ReadRowsRetryTest.java @@ -32,6 +32,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Queue; +import java.util.concurrent.TimeUnit; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -67,6 +68,7 @@ public void setUp() throws IOException { @After public void tearDown() throws Exception { client.close(); + client.awaitTermination(10, TimeUnit.SECONDS); } @Test diff --git a/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1beta2/BQTableSchemaToProtoDescriptorTest.java b/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1beta2/BQTableSchemaToProtoDescriptorTest.java index 8e08418237..06faf91959 100644 --- a/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1beta2/BQTableSchemaToProtoDescriptorTest.java +++ b/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1beta2/BQTableSchemaToProtoDescriptorTest.java @@ -65,9 +65,9 @@ private void mapDescriptorToCount(Descriptor descriptor, HashMap4.0.0 com.google.api.grpc grpc-google-cloud-bigquerystorage-v1 - 3.18.1-rc1-SNAPSHOT + 3.19.1-SNAPSHOT grpc-google-cloud-bigquerystorage-v1 GRPC library for grpc-google-cloud-bigquerystorage-v1 com.google.cloud google-cloud-bigquerystorage-parent - 3.18.1-rc1-SNAPSHOT + 3.19.1-SNAPSHOT diff --git a/grpc-google-cloud-bigquerystorage-v1alpha/pom.xml b/grpc-google-cloud-bigquerystorage-v1alpha/pom.xml index d28654f730..1077860269 100644 --- a/grpc-google-cloud-bigquerystorage-v1alpha/pom.xml +++ b/grpc-google-cloud-bigquerystorage-v1alpha/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-cloud-bigquerystorage-v1alpha - 3.18.1-rc1-SNAPSHOT + 3.19.1-SNAPSHOT grpc-google-cloud-bigquerystorage-v1alpha GRPC library for google-cloud-bigquerystorage com.google.cloud google-cloud-bigquerystorage-parent - 3.18.1-rc1-SNAPSHOT + 3.19.1-SNAPSHOT diff --git a/grpc-google-cloud-bigquerystorage-v1beta/pom.xml b/grpc-google-cloud-bigquerystorage-v1beta/pom.xml index 9fe4932514..a0a374f62b 100644 --- a/grpc-google-cloud-bigquerystorage-v1beta/pom.xml +++ b/grpc-google-cloud-bigquerystorage-v1beta/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-cloud-bigquerystorage-v1beta - 3.18.1-rc1-SNAPSHOT + 3.19.1-SNAPSHOT grpc-google-cloud-bigquerystorage-v1beta GRPC library for google-cloud-bigquerystorage com.google.cloud google-cloud-bigquerystorage-parent - 3.18.1-rc1-SNAPSHOT + 3.19.1-SNAPSHOT diff --git a/grpc-google-cloud-bigquerystorage-v1beta1/pom.xml b/grpc-google-cloud-bigquerystorage-v1beta1/pom.xml index 39cee18400..53821e5269 100644 --- a/grpc-google-cloud-bigquerystorage-v1beta1/pom.xml +++ b/grpc-google-cloud-bigquerystorage-v1beta1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-cloud-bigquerystorage-v1beta1 - 0.190.1-rc1-SNAPSHOT + 0.191.1-SNAPSHOT grpc-google-cloud-bigquerystorage-v1beta1 GRPC library for grpc-google-cloud-bigquerystorage-v1beta1 com.google.cloud google-cloud-bigquerystorage-parent - 3.18.1-rc1-SNAPSHOT + 3.19.1-SNAPSHOT diff --git a/grpc-google-cloud-bigquerystorage-v1beta2/pom.xml b/grpc-google-cloud-bigquerystorage-v1beta2/pom.xml index d0f24c801e..987fb5d4d5 100644 --- a/grpc-google-cloud-bigquerystorage-v1beta2/pom.xml +++ b/grpc-google-cloud-bigquerystorage-v1beta2/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-cloud-bigquerystorage-v1beta2 - 0.190.1-rc1-SNAPSHOT + 0.191.1-SNAPSHOT grpc-google-cloud-bigquerystorage-v1beta2 GRPC library for grpc-google-cloud-bigquerystorage-v1beta2 com.google.cloud google-cloud-bigquerystorage-parent - 3.18.1-rc1-SNAPSHOT + 3.19.1-SNAPSHOT diff --git a/pom.xml b/pom.xml index c1e588b01b..25936410e4 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.google.cloud google-cloud-bigquerystorage-parent pom - 3.18.1-rc1-SNAPSHOT + 3.19.1-SNAPSHOT BigQuery Storage Parent https://github.com/googleapis/java-bigquerystorage @@ -14,7 +14,7 @@ com.google.cloud sdk-platform-java-config - 3.54.1 + 3.54.2 @@ -83,57 +83,57 @@ com.google.api.grpc proto-google-cloud-bigquerystorage-v1beta - 3.18.1-rc1-SNAPSHOT + 3.19.1-SNAPSHOT com.google.api.grpc grpc-google-cloud-bigquerystorage-v1beta - 3.18.1-rc1-SNAPSHOT + 3.19.1-SNAPSHOT com.google.api.grpc proto-google-cloud-bigquerystorage-v1alpha - 3.18.1-rc1-SNAPSHOT + 3.19.1-SNAPSHOT com.google.api.grpc grpc-google-cloud-bigquerystorage-v1alpha - 3.18.1-rc1-SNAPSHOT + 3.19.1-SNAPSHOT com.google.api.grpc proto-google-cloud-bigquerystorage-v1beta1 - 0.190.1-rc1-SNAPSHOT + 0.191.1-SNAPSHOT com.google.api.grpc proto-google-cloud-bigquerystorage-v1beta2 - 0.190.1-rc1-SNAPSHOT + 0.191.1-SNAPSHOT com.google.api.grpc proto-google-cloud-bigquerystorage-v1 - 3.18.1-rc1-SNAPSHOT + 3.19.1-SNAPSHOT com.google.api.grpc grpc-google-cloud-bigquerystorage-v1beta1 - 0.190.1-rc1-SNAPSHOT + 0.191.1-SNAPSHOT com.google.api.grpc grpc-google-cloud-bigquerystorage-v1beta2 - 0.190.1-rc1-SNAPSHOT + 0.191.1-SNAPSHOT com.google.api.grpc grpc-google-cloud-bigquerystorage-v1 - 3.18.1-rc1-SNAPSHOT + 3.19.1-SNAPSHOT com.google.cloud google-cloud-bigquerystorage - 3.18.1-rc1-SNAPSHOT + 3.19.1-SNAPSHOT org.json diff --git a/proto-google-cloud-bigquerystorage-v1/pom.xml b/proto-google-cloud-bigquerystorage-v1/pom.xml index 51a0e0fdce..58908bf36a 100644 --- a/proto-google-cloud-bigquerystorage-v1/pom.xml +++ b/proto-google-cloud-bigquerystorage-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-bigquerystorage-v1 - 3.18.1-rc1-SNAPSHOT + 3.19.1-SNAPSHOT proto-google-cloud-bigquerystorage-v1 PROTO library for proto-google-cloud-bigquerystorage-v1 com.google.cloud google-cloud-bigquerystorage-parent - 3.18.1-rc1-SNAPSHOT + 3.19.1-SNAPSHOT diff --git a/proto-google-cloud-bigquerystorage-v1alpha/pom.xml b/proto-google-cloud-bigquerystorage-v1alpha/pom.xml index e7b84ca4e2..98b0389797 100644 --- a/proto-google-cloud-bigquerystorage-v1alpha/pom.xml +++ b/proto-google-cloud-bigquerystorage-v1alpha/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-bigquerystorage-v1alpha - 3.18.1-rc1-SNAPSHOT + 3.19.1-SNAPSHOT proto-google-cloud-bigquerystorage-v1alpha Proto library for google-cloud-bigquerystorage com.google.cloud google-cloud-bigquerystorage-parent - 3.18.1-rc1-SNAPSHOT + 3.19.1-SNAPSHOT diff --git a/proto-google-cloud-bigquerystorage-v1beta/pom.xml b/proto-google-cloud-bigquerystorage-v1beta/pom.xml index 70344beb6f..99289ebcb5 100644 --- a/proto-google-cloud-bigquerystorage-v1beta/pom.xml +++ b/proto-google-cloud-bigquerystorage-v1beta/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-bigquerystorage-v1beta - 3.18.1-rc1-SNAPSHOT + 3.19.1-SNAPSHOT proto-google-cloud-bigquerystorage-v1beta Proto library for google-cloud-bigquerystorage com.google.cloud google-cloud-bigquerystorage-parent - 3.18.1-rc1-SNAPSHOT + 3.19.1-SNAPSHOT diff --git a/proto-google-cloud-bigquerystorage-v1beta1/pom.xml b/proto-google-cloud-bigquerystorage-v1beta1/pom.xml index 3565beeed5..6340c517e7 100644 --- a/proto-google-cloud-bigquerystorage-v1beta1/pom.xml +++ b/proto-google-cloud-bigquerystorage-v1beta1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-bigquerystorage-v1beta1 - 0.190.1-rc1-SNAPSHOT + 0.191.1-SNAPSHOT proto-google-cloud-bigquerystorage-v1beta1 PROTO library for proto-google-cloud-bigquerystorage-v1beta1 com.google.cloud google-cloud-bigquerystorage-parent - 3.18.1-rc1-SNAPSHOT + 3.19.1-SNAPSHOT diff --git a/proto-google-cloud-bigquerystorage-v1beta2/pom.xml b/proto-google-cloud-bigquerystorage-v1beta2/pom.xml index bcd1472c95..ffd1f64db3 100644 --- a/proto-google-cloud-bigquerystorage-v1beta2/pom.xml +++ b/proto-google-cloud-bigquerystorage-v1beta2/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-bigquerystorage-v1beta2 - 0.190.1-rc1-SNAPSHOT + 0.191.1-SNAPSHOT proto-google-cloud-bigquerystorage-v1beta2 PROTO library for proto-google-cloud-bigquerystorage-v1beta2 com.google.cloud google-cloud-bigquerystorage-parent - 3.18.1-rc1-SNAPSHOT + 3.19.1-SNAPSHOT diff --git a/renovate.json b/renovate.json index 598f2acf29..1a342849b8 100644 --- a/renovate.json +++ b/renovate.json @@ -1,4 +1,6 @@ { + "prConcurrentLimit": 0, + "prHourlyLimit": 0, "extends": [ ":separateMajorReleases", ":combinePatchMinorReleases", diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml index 1f94cc455b..64c27e7a3f 100644 --- a/samples/snapshot/pom.xml +++ b/samples/snapshot/pom.xml @@ -30,7 +30,7 @@ com.google.cloud google-cloud-bigquerystorage - 3.18.1-rc1-SNAPSHOT + 3.19.1-SNAPSHOT diff --git a/versions.txt b/versions.txt index 87f37513c4..ef294be402 100644 --- a/versions.txt +++ b/versions.txt @@ -1,14 +1,14 @@ # Format: # module:released-version:current-version -google-cloud-bigquerystorage:3.18.0:3.18.1-rc1-SNAPSHOT -grpc-google-cloud-bigquerystorage-v1beta1:0.190.0:0.190.1-rc1-SNAPSHOT -grpc-google-cloud-bigquerystorage-v1beta2:0.190.0:0.190.1-rc1-SNAPSHOT -grpc-google-cloud-bigquerystorage-v1:3.18.0:3.18.1-rc1-SNAPSHOT -proto-google-cloud-bigquerystorage-v1beta1:0.190.0:0.190.1-rc1-SNAPSHOT -proto-google-cloud-bigquerystorage-v1beta2:0.190.0:0.190.1-rc1-SNAPSHOT -proto-google-cloud-bigquerystorage-v1:3.18.0:3.18.1-rc1-SNAPSHOT -grpc-google-cloud-bigquerystorage-v1alpha:3.18.0:3.18.1-rc1-SNAPSHOT -proto-google-cloud-bigquerystorage-v1alpha:3.18.0:3.18.1-rc1-SNAPSHOT -proto-google-cloud-bigquerystorage-v1beta:3.18.0:3.18.1-rc1-SNAPSHOT -grpc-google-cloud-bigquerystorage-v1beta:3.18.0:3.18.1-rc1-SNAPSHOT +google-cloud-bigquerystorage:3.19.0:3.19.1-SNAPSHOT +grpc-google-cloud-bigquerystorage-v1beta1:0.191.0:0.191.1-SNAPSHOT +grpc-google-cloud-bigquerystorage-v1beta2:0.191.0:0.191.1-SNAPSHOT +grpc-google-cloud-bigquerystorage-v1:3.19.0:3.19.1-SNAPSHOT +proto-google-cloud-bigquerystorage-v1beta1:0.191.0:0.191.1-SNAPSHOT +proto-google-cloud-bigquerystorage-v1beta2:0.191.0:0.191.1-SNAPSHOT +proto-google-cloud-bigquerystorage-v1:3.19.0:3.19.1-SNAPSHOT +grpc-google-cloud-bigquerystorage-v1alpha:3.19.0:3.19.1-SNAPSHOT +proto-google-cloud-bigquerystorage-v1alpha:3.19.0:3.19.1-SNAPSHOT +proto-google-cloud-bigquerystorage-v1beta:3.19.0:3.19.1-SNAPSHOT +grpc-google-cloud-bigquerystorage-v1beta:3.19.0:3.19.1-SNAPSHOT