From 440c88bd67e1c9d08445fe26b01bf243f7fd1ca4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Olav=20L=C3=B8ite?= Date: Tue, 23 Jul 2024 03:01:57 +0200 Subject: [PATCH 01/38] fix: make sure commitAsync always finishes (#3216) The future that is returned by commitAsync() seems to never finish in some cases. It is unknown exactly what causes it, and this change adds a number of safety precautions that should ensure that the future always returns a result eventually. This is always easier to debug and handle than a future that never returns a value. --- .../cloud/spanner/TransactionRunnerImpl.java | 62 +++++++++++++------ .../cloud/spanner/spi/v1/GapicSpannerRpc.java | 10 +++ .../cloud/spanner/spi/v1/SpannerRpc.java | 4 ++ .../google/cloud/spanner/SessionImplTest.java | 2 + .../spanner/TransactionContextImplTest.java | 3 + .../spanner/TransactionManagerImplTest.java | 5 ++ .../spanner/TransactionRunnerImplTest.java | 5 ++ 7 files changed, 72 insertions(+), 19 deletions(-) diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/TransactionRunnerImpl.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/TransactionRunnerImpl.java index 692a60e97b..7219389e77 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/TransactionRunnerImpl.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/TransactionRunnerImpl.java @@ -306,12 +306,23 @@ private void createTxnAsync(final SettableApiFuture res) { void commit() { try { - commitResponse = commitAsync().get(); - } catch (InterruptedException e) { + // Normally, Gax will take care of any timeouts, but we add a timeout for getting the value + // from the future here as well to make sure the call always finishes, even if the future + // never resolves. + commitResponse = + commitAsync() + .get( + rpc.getCommitRetrySettings().getTotalTimeout().getSeconds() + 5, + TimeUnit.SECONDS); + } catch (InterruptedException | TimeoutException e) { if (commitFuture != null) { commitFuture.cancel(true); } - throw SpannerExceptionFactory.propagateInterrupt(e); + if (e instanceof InterruptedException) { + throw SpannerExceptionFactory.propagateInterrupt((InterruptedException) e); + } else { + throw SpannerExceptionFactory.propagateTimeout((TimeoutException) e); + } } catch (ExecutionException e) { throw SpannerExceptionFactory.newSpannerException(e.getCause() == null ? e : e.getCause()); } @@ -422,6 +433,14 @@ public void run() { commitFuture.addListener( () -> { try (IScope ignore = tracer.withSpan(opSpan)) { + if (!commitFuture.isDone()) { + // This should not be possible, considering that we are in a listener for the + // future, but we add a result here as well as a safety precaution. + res.setException( + SpannerExceptionFactory.newSpannerException( + ErrorCode.INTERNAL, "commitFuture is not done")); + return; + } com.google.spanner.v1.CommitResponse proto = commitFuture.get(); if (!proto.hasCommitTimestamp()) { throw newSpannerException( @@ -430,20 +449,28 @@ public void run() { span.addAnnotation("Commit Done"); opSpan.end(); res.set(new CommitResponse(proto)); - } catch (Throwable e) { - if (e instanceof ExecutionException) { - e = - SpannerExceptionFactory.newSpannerException( - e.getCause() == null ? e : e.getCause()); - } else if (e instanceof InterruptedException) { - e = SpannerExceptionFactory.propagateInterrupt((InterruptedException) e); - } else { - e = SpannerExceptionFactory.newSpannerException(e); + } catch (Throwable throwable) { + SpannerException resultException; + try { + if (throwable instanceof ExecutionException) { + resultException = + SpannerExceptionFactory.asSpannerException( + throwable.getCause() == null ? throwable : throwable.getCause()); + } else if (throwable instanceof InterruptedException) { + resultException = + SpannerExceptionFactory.propagateInterrupt( + (InterruptedException) throwable); + } else { + resultException = SpannerExceptionFactory.asSpannerException(throwable); + } + span.addAnnotation("Commit Failed", resultException); + opSpan.setStatus(resultException); + opSpan.end(); + res.setException(onError(resultException, false)); + } catch (Throwable unexpectedError) { + // This is a safety precaution to make sure that a result is always returned. + res.setException(unexpectedError); } - span.addAnnotation("Commit Failed", e); - opSpan.setStatus(e); - opSpan.end(); - res.setException(onError((SpannerException) e, false)); } }, MoreExecutors.directExecutor()); @@ -451,9 +478,6 @@ public void run() { res.setException(SpannerExceptionFactory.propagateInterrupt(e)); } catch (TimeoutException e) { res.setException(SpannerExceptionFactory.propagateTimeout(e)); - } catch (ExecutionException e) { - res.setException( - SpannerExceptionFactory.newSpannerException(e.getCause() == null ? e : e.getCause())); } catch (Throwable e) { res.setException( SpannerExceptionFactory.newSpannerException(e.getCause() == null ? e : e.getCause())); diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java index b6016f04f7..2548e1fdc8 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java @@ -240,6 +240,7 @@ public class GapicSpannerRpc implements SpannerRpc { private final Set executeQueryRetryableCodes; private final RetrySettings readRetrySettings; private final Set readRetryableCodes; + private final RetrySettings commitRetrySettings; private final SpannerStub partitionedDmlStub; private final RetrySettings partitionedDmlRetrySettings; private final InstanceAdminStubSettings instanceAdminStubSettings; @@ -398,6 +399,8 @@ public GapicSpannerRpc(final SpannerOptions options) { options.getSpannerStubSettings().executeStreamingSqlSettings().getRetrySettings(); this.executeQueryRetryableCodes = options.getSpannerStubSettings().executeStreamingSqlSettings().getRetryableCodes(); + this.commitRetrySettings = + options.getSpannerStubSettings().commitSettings().getRetrySettings(); partitionedDmlRetrySettings = options .getSpannerStubSettings() @@ -508,6 +511,8 @@ public UnaryCallable createUnaryCalla this.readRetryableCodes = null; this.executeQueryRetrySettings = null; this.executeQueryRetryableCodes = null; + this.commitRetrySettings = + SpannerStubSettings.newBuilder().commitSettings().getRetrySettings(); this.partitionedDmlStub = null; this.databaseAdminStubSettings = null; this.instanceAdminStubSettings = null; @@ -1801,6 +1806,11 @@ public CommitResponse commit(CommitRequest commitRequest, @Nullable Map rollbackAsync(RollbackRequest request, @Nullable Map options) { GrpcCallContext context = diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/SpannerRpc.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/SpannerRpc.java index f063a7a313..f07a28fb91 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/SpannerRpc.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/SpannerRpc.java @@ -469,6 +469,10 @@ CommitResponse commit(CommitRequest commitRequest, @Nullable Map opti ApiFuture commitAsync( CommitRequest commitRequest, @Nullable Map options); + default RetrySettings getCommitRetrySettings() { + return SpannerStubSettings.newBuilder().commitSettings().getRetrySettings(); + } + void rollback(RollbackRequest request, @Nullable Map options) throws SpannerException; ApiFuture rollbackAsync(RollbackRequest request, @Nullable Map options); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionImplTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionImplTest.java index 72befe8a2b..2a850514d0 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionImplTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionImplTest.java @@ -138,6 +138,8 @@ public void setUp() { when(rpc.getExecuteQueryRetryableCodes()) .thenReturn( SpannerStubSettings.newBuilder().executeStreamingSqlSettings().getRetryableCodes()); + when(rpc.getCommitRetrySettings()) + .thenReturn(SpannerStubSettings.newBuilder().commitSettings().getRetrySettings()); session = spanner.getSessionClient(db).createSession(); Span oTspan = mock(Span.class); ISpan span = new OpenTelemetrySpan(oTspan); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TransactionContextImplTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TransactionContextImplTest.java index c1da423760..561bfb8900 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TransactionContextImplTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TransactionContextImplTest.java @@ -28,6 +28,7 @@ import com.google.api.core.ApiFutures; import com.google.cloud.spanner.TransactionRunnerImpl.TransactionContextImpl; import com.google.cloud.spanner.spi.v1.SpannerRpc; +import com.google.cloud.spanner.v1.stub.SpannerStubSettings; import com.google.protobuf.ByteString; import com.google.protobuf.Timestamp; import com.google.rpc.Code; @@ -80,6 +81,8 @@ public void setup() { when(tracer.spanBuilderWithExplicitParent( eq(SpannerImpl.BATCH_UPDATE), eq(span), any(Attributes.class))) .thenReturn(span); + when(rpc.getCommitRetrySettings()) + .thenReturn(SpannerStubSettings.newBuilder().commitSettings().getRetrySettings()); } private TransactionContextImpl createContext() { diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TransactionManagerImplTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TransactionManagerImplTest.java index dc28b333c4..c3fcf1c748 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TransactionManagerImplTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TransactionManagerImplTest.java @@ -35,6 +35,7 @@ import com.google.cloud.grpc.GrpcTransportOptions.ExecutorFactory; import com.google.cloud.spanner.TransactionManager.TransactionState; import com.google.cloud.spanner.spi.v1.SpannerRpc; +import com.google.cloud.spanner.v1.stub.SpannerStubSettings; import com.google.protobuf.ByteString; import com.google.protobuf.Empty; import com.google.spanner.v1.BeginTransactionRequest; @@ -248,6 +249,8 @@ public void usesPreparedTransaction() { com.google.protobuf.Timestamp.newBuilder() .setSeconds(System.currentTimeMillis() * 1000)) .build())); + when(rpc.getCommitRetrySettings()) + .thenReturn(SpannerStubSettings.newBuilder().commitSettings().getRetrySettings()); DatabaseId db = DatabaseId.of("test", "test", "test"); try (SpannerImpl spanner = new SpannerImpl(rpc, options)) { DatabaseClient client = spanner.getDatabaseClient(db); @@ -332,6 +335,8 @@ public void inlineBegin() { com.google.protobuf.Timestamp.newBuilder() .setSeconds(System.currentTimeMillis() * 1000)) .build())); + when(rpc.getCommitRetrySettings()) + .thenReturn(SpannerStubSettings.newBuilder().commitSettings().getRetrySettings()); DatabaseId db = DatabaseId.of("test", "test", "test"); try (SpannerImpl spanner = new SpannerImpl(rpc, options)) { DatabaseClient client = spanner.getDatabaseClient(db); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TransactionRunnerImplTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TransactionRunnerImplTest.java index 6a707a490d..f5d9f1841a 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TransactionRunnerImplTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TransactionRunnerImplTest.java @@ -35,6 +35,7 @@ import com.google.cloud.spanner.SessionClient.SessionId; import com.google.cloud.spanner.TransactionRunnerImpl.TransactionContextImpl; import com.google.cloud.spanner.spi.v1.SpannerRpc; +import com.google.cloud.spanner.v1.stub.SpannerStubSettings; import com.google.common.base.Preconditions; import com.google.protobuf.ByteString; import com.google.protobuf.Duration; @@ -141,6 +142,8 @@ public void setUp() { CommitResponse.newBuilder() .setCommitTimestamp(Timestamp.getDefaultInstance()) .build())); + when(rpc.getCommitRetrySettings()) + .thenReturn(SpannerStubSettings.newBuilder().commitSettings().getRetrySettings()); when(rpc.rollbackAsync(Mockito.any(RollbackRequest.class), Mockito.anyMap())) .thenReturn(ApiFutures.immediateFuture(Empty.getDefaultInstance())); Span oTspan = mock(Span.class); @@ -196,6 +199,8 @@ public void usesPreparedTransaction() { .setCommitTimestamp( Timestamp.newBuilder().setSeconds(System.currentTimeMillis() * 1000)) .build())); + when(rpc.getCommitRetrySettings()) + .thenReturn(SpannerStubSettings.newBuilder().commitSettings().getRetrySettings()); DatabaseId db = DatabaseId.of("test", "test", "test"); try (SpannerImpl spanner = new SpannerImpl(rpc, options)) { DatabaseClient client = spanner.getDatabaseClient(db); From 9de91d77e23460f5dd82bc7a9d90bc7ca9d196d3 Mon Sep 17 00:00:00 2001 From: rahul2393 Date: Fri, 26 Jul 2024 13:50:56 +0530 Subject: [PATCH 02/38] chore: skip clirr 7012 exceptions with grpc admin package (#3222) --- .../clirr-ignored-differences.xml | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 grpc-google-cloud-spanner-admin-database-v1/clirr-ignored-differences.xml diff --git a/grpc-google-cloud-spanner-admin-database-v1/clirr-ignored-differences.xml b/grpc-google-cloud-spanner-admin-database-v1/clirr-ignored-differences.xml new file mode 100644 index 0000000000..80e6f1d59c --- /dev/null +++ b/grpc-google-cloud-spanner-admin-database-v1/clirr-ignored-differences.xml @@ -0,0 +1,9 @@ + + + + + 7012 + com/google/spanner/admin/database/v1/* + * + + From c4c09dc3914121d629910349d85f4cc226631d5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Olav=20L=C3=B8ite?= Date: Mon, 29 Jul 2024 16:32:52 +0200 Subject: [PATCH 03/38] test: do not use RESOURCE_EXHAUSTED as it is retryable (#3227) The test used the error code RESOURCE_EXHAUSTED to indicate that the server could not create any more sessions. This error code is now retryable, causing the test to become flaky. Change the error code to one that is not retryable. Fixes #3224 --- .../com/google/cloud/spanner/BatchCreateSessionsTest.java | 4 ++-- .../java/com/google/cloud/spanner/MockSpannerServiceImpl.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/BatchCreateSessionsTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/BatchCreateSessionsTest.java index c252bb1923..8d359428c7 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/BatchCreateSessionsTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/BatchCreateSessionsTest.java @@ -207,13 +207,13 @@ public void testSpannerReturnsAllAvailableSessionsAndThenNoSessions() } @Test - public void testSpannerReturnsResourceExhausted() throws InterruptedException { + public void testSpannerReturnsFailedPrecondition() throws InterruptedException { int minSessions = 100; int maxSessions = 1000; int expectedSessions; DatabaseClientImpl client; // Make the first BatchCreateSessions return an error. - mockSpanner.addException(Status.RESOURCE_EXHAUSTED.asRuntimeException()); + mockSpanner.addException(Status.FAILED_PRECONDITION.asRuntimeException()); try (Spanner spanner = createSpanner(minSessions, maxSessions)) { // Create a database client which will create a session pool. client = diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MockSpannerServiceImpl.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MockSpannerServiceImpl.java index 54b992b69f..5266ecad7c 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MockSpannerServiceImpl.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MockSpannerServiceImpl.java @@ -808,7 +808,7 @@ public void batchCreateSessions( batchCreateSessionsExecutionTime.simulateExecutionTime( exceptions, stickyGlobalExceptions, freezeLock); if (sessions.size() >= maxTotalSessions) { - throw Status.RESOURCE_EXHAUSTED + throw Status.FAILED_PRECONDITION .withDescription("Maximum number of sessions reached") .asRuntimeException(); } From 13daf1f73ead8b1524d3f45ee9cba65cca5ea8a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Olav=20L=C3=B8ite?= Date: Tue, 30 Jul 2024 11:53:08 +0200 Subject: [PATCH 04/38] chore: remove unused multiplexed session code (#3156) Removes the unused code for multiplexed sessions in the session pool. All relevant code has been moved to the MultiplexedSessionDatabaseClient. --- .../com/google/cloud/spanner/SessionPool.java | 737 +----------------- .../MultiplexedSessionMaintainerTest.java | 310 -------- .../spanner/MultiplexedSessionPoolTest.java | 182 ----- .../google/cloud/spanner/SessionPoolTest.java | 11 - 4 files changed, 30 insertions(+), 1210 deletions(-) delete mode 100644 google-cloud-spanner/src/test/java/com/google/cloud/spanner/MultiplexedSessionMaintainerTest.java delete mode 100644 google-cloud-spanner/src/test/java/com/google/cloud/spanner/MultiplexedSessionPoolTest.java diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionPool.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionPool.java index f36da57a81..1819224495 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionPool.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionPool.java @@ -65,7 +65,6 @@ import com.google.cloud.spanner.SpannerImpl.ClosedException; import com.google.cloud.spanner.spi.v1.SpannerRpc; import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Function; import com.google.common.base.MoreObjects; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; @@ -107,9 +106,10 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Function; import java.util.logging.Level; import java.util.logging.Logger; +import javax.annotation.Nonnull; import javax.annotation.Nullable; import javax.annotation.concurrent.GuardedBy; import org.threeten.bp.Duration; @@ -144,14 +144,6 @@ void maybeWaitOnMinSessions() { ErrorCode.DEADLINE_EXCEEDED, "Timed out after waiting " + timeoutMillis + "ms for session pool creation"); } - - if (useMultiplexedSessions() - && !waitOnMultiplexedSessionsLatch.await(timeoutNanos, TimeUnit.NANOSECONDS)) { - final long timeoutMillis = options.getWaitForMinSessions().toMillis(); - throw SpannerExceptionFactory.newSpannerException( - ErrorCode.DEADLINE_EXCEEDED, - "Timed out after waiting " + timeoutMillis + "ms for multiplexed session creation"); - } } catch (InterruptedException e) { throw SpannerExceptionFactory.propagateInterrupt(e); } @@ -241,7 +233,7 @@ public ApiFuture setCallback(Executor exec, ReadyCallback cb) { private AutoClosingReadContext( Function delegateSupplier, SessionPool sessionPool, - SessionReplacementHandler sessionReplacementHandler, + SessionReplacementHandler sessionReplacementHandler, I session, boolean isSingleUse) { this.readContextDelegateSupplier = delegateSupplier; @@ -554,7 +546,7 @@ private static class AutoClosingReadTransaction AutoClosingReadTransaction( Function txnSupplier, SessionPool sessionPool, - SessionReplacementHandler sessionReplacementHandler, + SessionReplacementHandler sessionReplacementHandler, I session, boolean isSingleUse) { super(txnSupplier, sessionPool, sessionReplacementHandler, session, isSingleUse); @@ -590,23 +582,6 @@ public PooledSessionFuture replaceSession( } } - static class MultiplexedSessionReplacementHandler - implements SessionReplacementHandler { - @Override - public MultiplexedSessionFuture replaceSession( - SessionNotFoundException e, MultiplexedSessionFuture session) { - /** - * For multiplexed sessions, we would never obtain a {@link SessionNotFoundException}. Hence, - * this method will ideally never be invoked. - */ - logger.log( - Level.WARNING, - String.format( - "Replace session invoked for multiplexed session => %s", session.getName())); - throw e; - } - } - interface SessionNotFoundHandler { /** * Handles the given {@link SessionNotFoundException} by possibly converting it to a different @@ -781,10 +756,13 @@ public ApiFuture bufferAsync(Iterable mutations) { return delegate.bufferAsync(mutations); } + @SuppressWarnings("deprecation") @Override public ResultSetStats analyzeUpdate( Statement statement, QueryAnalyzeMode analyzeMode, UpdateOption... options) { - return analyzeUpdateStatement(statement, analyzeMode, options).getStats(); + try (ResultSet resultSet = analyzeUpdateStatement(statement, analyzeMode, options)) { + return resultSet.getStats(); + } } @Override @@ -870,7 +848,7 @@ private static class AutoClosingTransactionManager AutoClosingTransactionManager( T session, - SessionReplacementHandler sessionReplacementHandler, + SessionReplacementHandler sessionReplacementHandler, TransactionOption... options) { this.session = session; this.options = options; @@ -1000,7 +978,7 @@ private static final class SessionPoolTransactionRunner private SessionPoolTransactionRunner( I session, - SessionReplacementHandler sessionReplacementHandler, + SessionReplacementHandler sessionReplacementHandler, TransactionOption... options) { this.session = session; this.options = options; @@ -1032,6 +1010,7 @@ public T run(TransactionCallable callable) { session.get().markUsed(); return result; } catch (SpannerException e) { + //noinspection ThrowableNotThrown session.get().setLastException(e); throw e; } finally { @@ -1064,7 +1043,7 @@ private static class SessionPoolAsyncRunner implements private SessionPoolAsyncRunner( I session, - SessionReplacementHandler sessionReplacementHandler, + SessionReplacementHandler sessionReplacementHandler, TransactionOption... options) { this.session = session; this.options = options; @@ -1100,7 +1079,6 @@ public ApiFuture runAsync(final AsyncWork work, Executor executor) { session = sessionReplacementHandler.replaceSession( (SessionNotFoundException) se, session); - se = null; } catch (SessionNotFoundException e) { exception = e; break; @@ -1266,39 +1244,6 @@ public PooledSessionFuture get() { } } - class MultiplexedSessionFutureWrapper implements SessionFutureWrapper { - private ISpan span; - private volatile MultiplexedSessionFuture multiplexedSessionFuture; - - public MultiplexedSessionFutureWrapper(ISpan span) { - this.span = span; - } - - @Override - public MultiplexedSessionFuture get() { - if (resourceNotFoundException != null) { - span.addAnnotation("Database has been deleted"); - throw SpannerExceptionFactory.newSpannerException( - ErrorCode.NOT_FOUND, - String.format( - "The session pool has been invalidated because a previous RPC returned 'Database not found': %s", - resourceNotFoundException.getMessage()), - resourceNotFoundException); - } - if (multiplexedSessionFuture == null) { - synchronized (lock) { - if (multiplexedSessionFuture == null) { - // Creating a new reference where the request's span state can be stored. - MultiplexedSessionFuture multiplexedSessionFuture = new MultiplexedSessionFuture(span); - this.multiplexedSessionFuture = multiplexedSessionFuture; - return multiplexedSessionFuture; - } - } - } - return multiplexedSessionFuture; - } - } - interface SessionFuture extends Session { /** @@ -1318,8 +1263,8 @@ class PooledSessionFuture extends SimpleForwardingListenableFuture(this, pooledSessionReplacementHandler, options); } @Override @@ -1563,7 +1508,7 @@ PooledSession get(final boolean eligibleForLongRunning) { res.markBusy(span); span.addAnnotation("Using Session", "sessionId", res.getName()); synchronized (lock) { - incrementNumSessionsInUse(false); + incrementNumSessionsInUse(); checkedOutSessions.add(this); } res.eligibleForLongRunning = eligibleForLongRunning; @@ -1581,247 +1526,6 @@ PooledSession get(final boolean eligibleForLongRunning) { } } - class MultiplexedSessionFuture implements SessionFuture { - - private final ISpan span; - private volatile MultiplexedSession multiplexedSession; - - MultiplexedSessionFuture(ISpan span) { - this.span = span; - } - - @Override - public Timestamp write(Iterable mutations) throws SpannerException { - return writeWithOptions(mutations).getCommitTimestamp(); - } - - @Override - public CommitResponse writeWithOptions( - Iterable mutations, TransactionOption... options) throws SpannerException { - try { - return get().writeWithOptions(mutations, options); - } finally { - close(); - } - } - - @Override - public Timestamp writeAtLeastOnce(Iterable mutations) throws SpannerException { - return writeAtLeastOnceWithOptions(mutations).getCommitTimestamp(); - } - - @Override - public CommitResponse writeAtLeastOnceWithOptions( - Iterable mutations, TransactionOption... options) throws SpannerException { - try { - return get().writeAtLeastOnceWithOptions(mutations, options); - } finally { - close(); - } - } - - @Override - public ServerStream batchWriteAtLeastOnce( - Iterable mutationGroups, TransactionOption... options) - throws SpannerException { - try { - return get().batchWriteAtLeastOnce(mutationGroups, options); - } finally { - close(); - } - } - - @Override - public ReadContext singleUse() { - try { - return new AutoClosingReadContext<>( - session -> { - MultiplexedSession multiplexedSession = session.get(); - return multiplexedSession.getDelegate().singleUse(); - }, - SessionPool.this, - multiplexedSessionReplacementHandler, - this, - true); - } catch (Exception e) { - close(); - throw e; - } - } - - @Override - public ReadContext singleUse(final TimestampBound bound) { - try { - return new AutoClosingReadContext<>( - session -> { - MultiplexedSession multiplexedSession = session.get(); - return multiplexedSession.getDelegate().singleUse(bound); - }, - SessionPool.this, - multiplexedSessionReplacementHandler, - this, - true); - } catch (Exception e) { - close(); - throw e; - } - } - - @Override - public ReadOnlyTransaction singleUseReadOnlyTransaction() { - return internalReadOnlyTransaction( - session -> { - MultiplexedSession multiplexedSession = session.get(); - return multiplexedSession.getDelegate().singleUseReadOnlyTransaction(); - }, - true); - } - - @Override - public ReadOnlyTransaction singleUseReadOnlyTransaction(final TimestampBound bound) { - return internalReadOnlyTransaction( - session -> { - MultiplexedSession multiplexedSession = session.get(); - return multiplexedSession.getDelegate().singleUseReadOnlyTransaction(bound); - }, - true); - } - - @Override - public ReadOnlyTransaction readOnlyTransaction() { - return internalReadOnlyTransaction( - session -> { - MultiplexedSession multiplexedSession = session.get(); - return multiplexedSession.getDelegate().readOnlyTransaction(); - }, - false); - } - - @Override - public ReadOnlyTransaction readOnlyTransaction(final TimestampBound bound) { - return internalReadOnlyTransaction( - session -> { - MultiplexedSession multiplexedSession = session.get(); - return multiplexedSession.getDelegate().readOnlyTransaction(bound); - }, - false); - } - - private ReadOnlyTransaction internalReadOnlyTransaction( - Function transactionSupplier, - boolean isSingleUse) { - try { - return new AutoClosingReadTransaction<>( - transactionSupplier, - SessionPool.this, - multiplexedSessionReplacementHandler, - this, - isSingleUse); - } catch (Exception e) { - close(); - throw e; - } - } - - @Override - public TransactionRunner readWriteTransaction(TransactionOption... options) { - return new SessionPoolTransactionRunner<>( - this, multiplexedSessionReplacementHandler, options); - } - - @Override - public TransactionManager transactionManager(TransactionOption... options) { - return new AutoClosingTransactionManager<>( - this, multiplexedSessionReplacementHandler, options); - } - - @Override - public AsyncRunner runAsync(TransactionOption... options) { - return new SessionPoolAsyncRunner(this, multiplexedSessionReplacementHandler, options); - } - - @Override - public AsyncTransactionManager transactionManagerAsync(TransactionOption... options) { - return new SessionPoolAsyncTransactionManager<>( - multiplexedSessionReplacementHandler, this, options); - } - - @Override - public long executePartitionedUpdate(Statement stmt, UpdateOption... options) { - try { - return get().executePartitionedUpdate(stmt, options); - } finally { - close(); - } - } - - @Override - public String getName() { - return get().getName(); - } - - @Override - public void close() { - try { - asyncClose().get(); - } catch (InterruptedException e) { - throw SpannerExceptionFactory.propagateInterrupt(e); - } catch (ExecutionException e) { - throw asSpannerException(e.getCause()); - } - } - - @Override - public ApiFuture asyncClose() { - MultiplexedSession delegate = getOrNull(); - if (delegate != null) { - return delegate.asyncClose(); - } - return ApiFutures.immediateFuture(Empty.getDefaultInstance()); - } - - private MultiplexedSession getOrNull() { - try { - return get(); - } catch (Throwable ignore) { - // this exception will never be thrown for a multiplexed session since the Future - // object is already initialised. - return null; - } - } - - @Override - public MultiplexedSession get() { - try { - if (multiplexedSession == null) { - boolean created = false; - synchronized (this) { - if (multiplexedSession == null) { - SessionImpl sessionImpl = - new SessionImpl( - sessionClient.getSpanner(), currentMultiplexedSessionReference.get().get()); - MultiplexedSession multiplexedSession = new MultiplexedSession(sessionImpl); - multiplexedSession.markBusy(span); - span.addAnnotation("Using Session", "sessionId", multiplexedSession.getName()); - this.multiplexedSession = multiplexedSession; - created = true; - } - } - if (created) { - synchronized (lock) { - incrementNumSessionsInUse(true); - } - } - } - return multiplexedSession; - } catch (ExecutionException e) { - throw SpannerExceptionFactory.newSpannerException(e.getCause()); - } catch (InterruptedException e) { - throw SpannerExceptionFactory.propagateInterrupt(e); - } - } - } - interface CachedSession extends Session { SessionImpl getDelegate(); @@ -1832,9 +1536,6 @@ interface CachedSession extends Session { SpannerException setLastException(SpannerException exception); - // TODO This method can be removed once we fully migrate to multiplexed sessions. - boolean isAllowReplacing(); - AsyncTransactionManagerImpl transactionManagerAsync(TransactionOption... options); void setAllowReplacing(boolean b); @@ -2024,7 +1725,7 @@ public void close() { if ((lastException != null && isSessionNotFound(lastException)) || isRemovedFromPool) { invalidateSession(this); } else { - if (lastException != null && isDatabaseOrInstanceNotFound(lastException)) { + if (isDatabaseOrInstanceNotFound(lastException)) { // Mark this session pool as no longer valid and then release the session into the pool as // there is nothing we can do with it anyways. synchronized (lock) { @@ -2116,8 +1817,7 @@ public SpannerException setLastException(SpannerException exception) { return exception; } - @Override - public boolean isAllowReplacing() { + boolean isAllowReplacing() { return this.allowReplacing; } @@ -2127,172 +1827,12 @@ public TransactionManager transactionManager(TransactionOption... options) { } } - class MultiplexedSession implements CachedSession { - final SessionImpl delegate; - private volatile SpannerException lastException; - - MultiplexedSession(SessionImpl session) { - this.delegate = session; - } - - @Override - public boolean isAllowReplacing() { - // for multiplexed session there is only 1 session, hence there is nothing that we - // can replace. - return false; - } - - @Override - public void setAllowReplacing(boolean allowReplacing) { - // for multiplexed session there is only 1 session, there is nothing that can be replaced. - // hence this is no-op. - } - - @Override - public void markBusy(ISpan span) { - this.delegate.setCurrentSpan(span); - } - - @Override - public void markUsed() { - // no-op for a multiplexed session since we don't track the last-used time - // in case of multiplexed session - } - - @Override - public SpannerException setLastException(SpannerException exception) { - this.lastException = exception; - return exception; - } - - @Override - public SessionImpl getDelegate() { - return delegate; - } - - @Override - public Timestamp write(Iterable mutations) throws SpannerException { - throw SpannerExceptionFactory.newSpannerException( - ErrorCode.UNIMPLEMENTED, "Unimplemented with Multiplexed Session"); - } - - @Override - public CommitResponse writeWithOptions( - Iterable mutations, TransactionOption... options) throws SpannerException { - throw SpannerExceptionFactory.newSpannerException( - ErrorCode.UNIMPLEMENTED, "Unimplemented with Multiplexed Session"); - } - - @Override - public Timestamp writeAtLeastOnce(Iterable mutations) throws SpannerException { - throw SpannerExceptionFactory.newSpannerException( - ErrorCode.UNIMPLEMENTED, "Unimplemented with Multiplexed Session"); - } - - @Override - public CommitResponse writeAtLeastOnceWithOptions( - Iterable mutations, TransactionOption... options) throws SpannerException { - throw SpannerExceptionFactory.newSpannerException( - ErrorCode.UNIMPLEMENTED, "Unimplemented with Multiplexed Session"); - } - - @Override - public ServerStream batchWriteAtLeastOnce( - Iterable mutationGroups, TransactionOption... options) - throws SpannerException { - throw SpannerExceptionFactory.newSpannerException( - ErrorCode.UNIMPLEMENTED, "Unimplemented with Multiplexed Session"); - } - - @Override - public ReadContext singleUse() { - return delegate.singleUse(); - } - - @Override - public ReadContext singleUse(TimestampBound bound) { - return delegate.singleUse(bound); - } - - @Override - public ReadOnlyTransaction singleUseReadOnlyTransaction() { - return delegate.singleUseReadOnlyTransaction(); - } - - @Override - public ReadOnlyTransaction singleUseReadOnlyTransaction(TimestampBound bound) { - return delegate.singleUseReadOnlyTransaction(bound); - } - - @Override - public ReadOnlyTransaction readOnlyTransaction() { - return delegate.readOnlyTransaction(); - } - - @Override - public ReadOnlyTransaction readOnlyTransaction(TimestampBound bound) { - return delegate.readOnlyTransaction(bound); - } - - @Override - public TransactionRunner readWriteTransaction(TransactionOption... options) { - throw SpannerExceptionFactory.newSpannerException( - ErrorCode.UNIMPLEMENTED, "Unimplemented with Multiplexed Session"); - } - - @Override - public TransactionManager transactionManager(TransactionOption... options) { - throw SpannerExceptionFactory.newSpannerException( - ErrorCode.UNIMPLEMENTED, "Unimplemented with Multiplexed Session"); - } - - @Override - public AsyncRunner runAsync(TransactionOption... options) { - throw SpannerExceptionFactory.newSpannerException( - ErrorCode.UNIMPLEMENTED, "Unimplemented with Multiplexed Session"); - } - - @Override - public AsyncTransactionManagerImpl transactionManagerAsync(TransactionOption... options) { - throw SpannerExceptionFactory.newSpannerException( - ErrorCode.UNIMPLEMENTED, "Unimplemented with Multiplexed Session"); - } - - @Override - public long executePartitionedUpdate(Statement stmt, UpdateOption... options) { - throw SpannerExceptionFactory.newSpannerException( - ErrorCode.UNIMPLEMENTED, "Unimplemented with Multiplexed Session"); - } - - @Override - public String getName() { - return delegate.getName(); - } - - @Override - public void close() { - synchronized (lock) { - if (lastException != null && isDatabaseOrInstanceNotFound(lastException)) { - SessionPool.this.resourceNotFoundException = - MoreObjects.firstNonNull( - SessionPool.this.resourceNotFoundException, - (ResourceNotFoundException) lastException); - } - } - } - - @Override - public ApiFuture asyncClose() { - close(); - return ApiFutures.immediateFuture(Empty.getDefaultInstance()); - } - } - private final class WaiterFuture extends ForwardingListenableFuture { private static final long MAX_SESSION_WAIT_TIMEOUT = 240_000L; private final SettableFuture waiter = SettableFuture.create(); @Override + @Nonnull protected ListenableFuture delegate() { return waiter; } @@ -2310,7 +1850,7 @@ public PooledSession get() { long currentTimeout = options.getInitialWaitForSessionTimeoutMillis(); while (true) { ISpan span = tracer.spanBuilder(WAIT_FOR_SESSION); - try (IScope waitScope = tracer.withSpan(span)) { + try (IScope ignore = tracer.withSpan(span)) { PooledSession s = pollUninterruptiblyWithTimeout(currentTimeout, options.getAcquireSessionTimeout()); if (s == null) { @@ -2395,9 +1935,6 @@ private PooledSession pollUninterruptiblyWithTimeout( */ final class PoolMaintainer { - // Delay post which the maintainer will retry creating/replacing the current multiplexed session - private final Duration multiplexedSessionCreationRetryDelay = Duration.ofMinutes(10); - // Length of the window in millis over which we keep track of maximum number of concurrent // sessions in use. private final Duration windowLength = Duration.ofMillis(TimeUnit.MINUTES.toMillis(10)); @@ -2421,8 +1958,6 @@ final class PoolMaintainer { */ @VisibleForTesting Instant lastExecutionTime; - @VisibleForTesting Instant multiplexedSessionReplacementAttemptTime; - /** * The previous numSessionsAcquired seen by the maintainer. This is used to calculate the * transactions per second, which again is used to determine whether to randomize the order of @@ -2440,7 +1975,6 @@ final class PoolMaintainer { void init() { lastExecutionTime = clock.instant(); - multiplexedSessionReplacementAttemptTime = clock.instant(); // Scheduled pool maintenance worker. synchronized (lock) { @@ -2483,7 +2017,6 @@ void maintainPool() { this.prevNumSessionsAcquired = SessionPool.this.numSessionsAcquired; } Instant currTime = clock.instant(); - maintainMultiplexedSession(currTime); removeIdleSessions(currTime); // Now go over all the remaining sessions and see if they need to be kept alive explicitly. keepAliveSessions(currTime); @@ -2652,44 +2185,6 @@ private void removeLongRunningSessions( } } } - - void maintainMultiplexedSession(Instant currentTime) { - try { - if (useMultiplexedSessions()) { - if (currentMultiplexedSessionReference.get().isDone()) { - SessionReference sessionReference = getMultiplexedSessionInstance(); - if (sessionReference != null - && isMultiplexedSessionStale(sessionReference, currentTime)) { - final Instant minExecutionTime = - multiplexedSessionReplacementAttemptTime.plus( - multiplexedSessionCreationRetryDelay); - if (currentTime.isBefore(minExecutionTime)) { - return; - } - /* - This will attempt to create a new multiplexed session. if successfully created then - the existing session will be replaced. Note that there maybe active transactions - running on the stale session. Hence, it is important that we only replace the reference - and not invoke a DeleteSession RPC. - */ - maybeCreateMultiplexedSession(multiplexedMaintainerConsumer); - - // update this only after we have attempted to replace the multiplexed session - multiplexedSessionReplacementAttemptTime = currentTime; - } - } - } - } catch (final Throwable t) { - logger.log(Level.WARNING, "Failed to maintain multiplexed session", t); - } - } - - boolean isMultiplexedSessionStale(SessionReference sessionReference, Instant currentTime) { - final Duration durationFromCreationTime = - Duration.between(sessionReference.getCreateTime(), currentTime); - return durationFromCreationTime.compareTo(options.getMultiplexedSessionMaintenanceDuration()) - > 0; - } } enum Position { @@ -2754,9 +2249,6 @@ enum Position { @GuardedBy("lock") private ResourceNotFoundException resourceNotFoundException; - @GuardedBy("lock") - private boolean stopAutomaticPrepare; - @GuardedBy("lock") private final LinkedList sessions = new LinkedList<>(); @@ -2766,9 +2258,6 @@ enum Position { @GuardedBy("lock") private int numSessionsBeingCreated = 0; - @GuardedBy("lock") - private boolean multiplexedSessionBeingCreated = false; - @GuardedBy("lock") private int numSessionsInUse = 0; @@ -2790,10 +2279,7 @@ enum Position { @GuardedBy("lock") private long numLeakedSessionsRemoved = 0; - private AtomicLong numWaiterTimeouts = new AtomicLong(); - - private final AtomicReference> - currentMultiplexedSessionReference = new AtomicReference<>(SettableApiFuture.create()); + private final AtomicLong numWaiterTimeouts = new AtomicLong(); @GuardedBy("lock") private final Set allSessions = new HashSet<>(); @@ -2807,21 +2293,12 @@ enum Position { private final SessionConsumer sessionConsumer = new SessionConsumerImpl(); - private final MultiplexedSessionInitializationConsumer multiplexedSessionInitializationConsumer = - new MultiplexedSessionInitializationConsumer(); - private final MultiplexedSessionMaintainerConsumer multiplexedMaintainerConsumer = - new MultiplexedSessionMaintainerConsumer(); - @VisibleForTesting Function idleSessionRemovedListener; @VisibleForTesting Function longRunningSessionRemovedListener; - @VisibleForTesting Function multiplexedSessionRemovedListener; private final CountDownLatch waitOnMinSessionsLatch; - private final CountDownLatch waitOnMultiplexedSessionsLatch; - private final SessionReplacementHandler pooledSessionReplacementHandler = + private final PooledSessionReplacementHandler pooledSessionReplacementHandler = new PooledSessionReplacementHandler(); - private static final SessionReplacementHandler multiplexedSessionReplacementHandler = - new MultiplexedSessionReplacementHandler(); /** * Create a session pool with the given options and for the given database. It will also start @@ -2965,13 +2442,6 @@ private SessionPool( openTelemetry, attributes, numMultiplexedSessionsAcquired, numMultiplexedSessionsReleased); this.waitOnMinSessionsLatch = options.getMinSessions() > 0 ? new CountDownLatch(1) : new CountDownLatch(0); - this.waitOnMultiplexedSessionsLatch = new CountDownLatch(1); - } - - // TODO: Remove once all code for multiplexed sessions has been removed from the pool. - private boolean useMultiplexedSessions() { - // Multiplexed sessions have moved to MultiplexedSessionDatabaseClient - return false; } /** @@ -3007,7 +2477,7 @@ Dialect getDialect() { } } - SessionReplacementHandler getPooledSessionReplacementHandler() { + PooledSessionReplacementHandler getPooledSessionReplacementHandler() { return pooledSessionReplacementHandler; } @@ -3087,13 +2557,6 @@ int getTotalSessionsPlusNumSessionsBeingCreated() { } } - @VisibleForTesting - boolean isMultiplexedSessionBeingCreated() { - synchronized (lock) { - return multiplexedSessionBeingCreated; - } - } - @VisibleForTesting long getNumWaiterTimeouts() { return numWaiterTimeouts.get(); @@ -3105,9 +2568,6 @@ private void initPool() { if (options.getMinSessions() > 0) { createSessions(options.getMinSessions(), true); } - if (useMultiplexedSessions()) { - maybeCreateMultiplexedSession(multiplexedSessionInitializationConsumer); - } } } @@ -3173,36 +2633,8 @@ boolean isValid() { * Returns a multiplexed session. The method fallbacks to a regular session if {@link * SessionPoolOptions#getUseMultiplexedSession} is not set. */ - SessionFutureWrapper getMultiplexedSessionWithFallback() throws SpannerException { - if (useMultiplexedSessions()) { - ISpan span = tracer.getCurrentSpan(); - try { - return getWrappedMultiplexedSessionFuture(span); - } catch (Throwable t) { - span.addAnnotation("No multiplexed session available."); - throw asSpannerException(t.getCause()); - } - } else { - return new PooledSessionFutureWrapper(getSession()); - } - } - - SessionFutureWrapper getWrappedMultiplexedSessionFuture(ISpan span) { - return new MultiplexedSessionFutureWrapper(span); - } - - /** - * This method is a blocking method. It will block until the underlying {@code - * SettableApiFuture} is resolved. - */ - SessionReference getMultiplexedSessionInstance() { - try { - return currentMultiplexedSessionReference.get().get(); - } catch (InterruptedException e) { - throw SpannerExceptionFactory.propagateInterrupt(e); - } catch (ExecutionException e) { - throw asSpannerException(e.getCause()); - } + PooledSessionFutureWrapper getMultiplexedSessionWithFallback() throws SpannerException { + return new PooledSessionFutureWrapper(getSession()); } /** @@ -3271,14 +2703,12 @@ private PooledSessionFuture checkoutSession( return res; } - private void incrementNumSessionsInUse(boolean isMultiplexed) { + private void incrementNumSessionsInUse() { synchronized (lock) { - if (!isMultiplexed) { - if (maxSessionsInUse < ++numSessionsInUse) { - maxSessionsInUse = numSessionsInUse; - } - numSessionsAcquired++; + if (maxSessionsInUse < ++numSessionsInUse) { + maxSessionsInUse = numSessionsInUse; } + numSessionsAcquired++; } } @@ -3496,7 +2926,7 @@ static boolean isUnbalanced( private void handleCreateSessionsFailure(SpannerException e, int count) { synchronized (lock) { for (int i = 0; i < count; i++) { - if (waiters.size() > 0) { + if (!waiters.isEmpty()) { waiters.poll().put(e); } else { break; @@ -3638,20 +3068,6 @@ private boolean canCreateSession() { } } - private void maybeCreateMultiplexedSession(SessionConsumer sessionConsumer) { - synchronized (lock) { - if (!multiplexedSessionBeingCreated) { - logger.log(Level.FINE, String.format("Creating multiplexed sessions")); - try { - multiplexedSessionBeingCreated = true; - sessionClient.asyncCreateMultiplexedSession(sessionConsumer); - } catch (Throwable ignore) { - // such an exception will never be thrown. the exception will be passed onto the consumer. - } - } - } - } - private void createSessions(final int sessionCount, boolean distributeOverChannels) { logger.log(Level.FINE, String.format("Creating %d sessions", sessionCount)); synchronized (lock) { @@ -3674,99 +3090,6 @@ private void createSessions(final int sessionCount, boolean distributeOverChanne } } - /** - * Callback interface which is invoked when a multiplexed session is being replaced by the - * background maintenance thread. When a multiplexed session creation fails during background - * thread, it would simply log the exception and retry the session creation in the next background - * thread invocation. - * - *

This consumer is not used when the multiplexed session is getting initialized for the first - * time during application startup. We instead use {@link - * MultiplexedSessionInitializationConsumer} for the first time when multiplexed session is - * getting created. - */ - class MultiplexedSessionMaintainerConsumer implements SessionConsumer { - @Override - public void onSessionReady(SessionImpl sessionImpl) { - final SessionReference sessionReference = sessionImpl.getSessionReference(); - final SettableFuture settableFuture = SettableFuture.create(); - settableFuture.set(sessionReference); - - synchronized (lock) { - SessionReference oldSession = null; - if (currentMultiplexedSessionReference.get().isDone()) { - oldSession = getMultiplexedSessionInstance(); - } - SettableApiFuture settableApiFuture = SettableApiFuture.create(); - settableApiFuture.set(sessionReference); - currentMultiplexedSessionReference.set(settableApiFuture); - if (oldSession != null) { - logger.log( - Level.INFO, - String.format( - "Removed Multiplexed Session => %s created at => %s", - oldSession.getName(), oldSession.getCreateTime())); - if (multiplexedSessionRemovedListener != null) { - multiplexedSessionRemovedListener.apply(oldSession); - } - } - multiplexedSessionBeingCreated = false; - } - } - - /** - * Method which logs the exception so that session creation can be re-attempted in the next - * background thread invocation. - */ - @Override - public void onSessionCreateFailure(Throwable t, int createFailureForSessionCount) { - synchronized (lock) { - multiplexedSessionBeingCreated = false; - } - logger.log( - Level.WARNING, - String.format( - "Failed to create multiplexed session. " - + "Pending replacing stale multiplexed session", - t)); - } - } - - /** - * Callback interface which is invoked when a multiplexed session is getting initialised for the - * first time when a session is getting created. - */ - class MultiplexedSessionInitializationConsumer implements SessionConsumer { - @Override - public void onSessionReady(SessionImpl sessionImpl) { - final SessionReference sessionReference = sessionImpl.getSessionReference(); - synchronized (lock) { - SettableApiFuture settableApiFuture = - currentMultiplexedSessionReference.get(); - settableApiFuture.set(sessionReference); - multiplexedSessionBeingCreated = false; - waitOnMultiplexedSessionsLatch.countDown(); - } - } - - /** - * When a multiplexed session fails during initialization we would like all pending threads to - * receive the exception and throw the error. This is done because at the time of start up there - * is no other multiplexed session which could have been assigned to the pending requests. - */ - @Override - public void onSessionCreateFailure(Throwable t, int createFailureForSessionCount) { - synchronized (lock) { - multiplexedSessionBeingCreated = false; - if (isDatabaseOrInstanceNotFound(asSpannerException(t))) { - setResourceNotFoundException((ResourceNotFoundException) t); - poolMaintainer.close(); - } - currentMultiplexedSessionReference.get().setException(asSpannerException(t)); - } - } - } - /** * {@link SessionConsumer} that receives the created sessions from a {@link SessionClient} and * releases these into the pool. The session pool only needs one instance of this, as all sessions diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MultiplexedSessionMaintainerTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MultiplexedSessionMaintainerTest.java deleted file mode 100644 index ca7f838689..0000000000 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MultiplexedSessionMaintainerTest.java +++ /dev/null @@ -1,310 +0,0 @@ -/* - * Copyright 2024 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.cloud.spanner; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.mockito.MockitoAnnotations.initMocks; - -import com.google.cloud.Timestamp; -import com.google.cloud.spanner.SessionPool.CachedSession; -import com.google.cloud.spanner.SessionPool.MultiplexedSessionInitializationConsumer; -import com.google.cloud.spanner.SessionPool.MultiplexedSessionMaintainerConsumer; -import com.google.cloud.spanner.SessionPool.Position; -import com.google.cloud.spanner.SessionPool.SessionFutureWrapper; -import io.opencensus.trace.Tracing; -import io.opentelemetry.api.OpenTelemetry; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.stream.Collectors; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; -import org.mockito.Mock; -import org.threeten.bp.Duration; -import org.threeten.bp.Instant; - -@RunWith(JUnit4.class) -public class MultiplexedSessionMaintainerTest extends BaseSessionPoolTest { - - private ExecutorService executor = Executors.newSingleThreadExecutor(); - private @Mock SpannerImpl client; - private @Mock SessionClient sessionClient; - private @Mock SpannerOptions spannerOptions; - private DatabaseId db = DatabaseId.of("projects/p/instances/i/databases/unused"); - private SessionPoolOptions options; - private FakeClock clock = new FakeClock(); - private List multiplexedSessionsRemoved = new ArrayList<>(); - - @BeforeClass - public static void checkUsesMultiplexedSessionPool() { - assumeTrue("Only run if the maintainer in the session pool is used", false); - } - - @Before - public void setUp() { - initMocks(this); - when(client.getOptions()).thenReturn(spannerOptions); - when(client.getSessionClient(db)).thenReturn(sessionClient); - when(sessionClient.getSpanner()).thenReturn(client); - when(spannerOptions.getNumChannels()).thenReturn(4); - when(spannerOptions.getDatabaseRole()).thenReturn("role"); - options = - SessionPoolOptions.newBuilder() - .setMinSessions(1) - .setMaxIdleSessions(1) - .setMaxSessions(5) - .setIncStep(1) - .setKeepAliveIntervalMinutes(2) - .setUseMultiplexedSession(true) - .setPoolMaintainerClock(clock) - .build(); - when(spannerOptions.getSessionPoolOptions()).thenReturn(options); - assumeTrue(options.getUseMultiplexedSession()); - multiplexedSessionsRemoved.clear(); - } - - @Test - public void testMaintainMultiplexedSession_whenNewSessionCreated_assertThatStaleSessionIsRemoved() - throws Exception { - doAnswer( - invocation -> { - MultiplexedSessionInitializationConsumer consumer = - invocation.getArgument(0, MultiplexedSessionInitializationConsumer.class); - ReadContext mockContext = mock(ReadContext.class); - Timestamp timestamp = - Timestamp.ofTimeSecondsAndNanos( - Instant.ofEpochMilli(clock.currentTimeMillis.get()).getEpochSecond(), 0); - consumer.onSessionReady( - setupMockSession( - buildMockMultiplexedSession(client, mockContext, timestamp.toProto()), - mockContext)); - return null; - }) - .when(sessionClient) - .asyncCreateMultiplexedSession(any(MultiplexedSessionInitializationConsumer.class)); - doAnswer( - invocation -> { - MultiplexedSessionMaintainerConsumer consumer = - invocation.getArgument(0, MultiplexedSessionMaintainerConsumer.class); - ReadContext mockContext = mock(ReadContext.class); - Timestamp timestamp = - Timestamp.ofTimeSecondsAndNanos( - Instant.ofEpochMilli(clock.currentTimeMillis.get()).getEpochSecond(), 0); - consumer.onSessionReady( - setupMockSession( - buildMockMultiplexedSession(client, mockContext, timestamp.toProto()), - mockContext)); - return null; - }) - .when(sessionClient) - .asyncCreateMultiplexedSession(any(MultiplexedSessionMaintainerConsumer.class)); - - SessionPool pool = createPool(); - - // Run one maintenance loop. - CachedSession session1 = pool.getMultiplexedSessionWithFallback().get().get(); - runMaintenanceLoop(clock, pool, 1); - assertTrue(multiplexedSessionsRemoved.isEmpty()); - - // Advance clock by 8 days - clock.currentTimeMillis.addAndGet(Duration.ofDays(8).toMillis()); - - // Run second maintenance loop. the first session would now be stale since it has now existed - // for more than 7 days. - runMaintenanceLoop(clock, pool, 1); - - CachedSession session2 = pool.getMultiplexedSessionWithFallback().get().get(); - assertNotEquals(session1.getName(), session2.getName()); - assertEquals(1, multiplexedSessionsRemoved.size()); - assertTrue(getNameOfSessionRemoved().contains(session1.getName())); - - // Advance clock by 8 days - clock.currentTimeMillis.addAndGet(Duration.ofDays(8).toMillis()); - - // Run third maintenance loop. the second session would now be stale since it has now existed - // for more than 7 days - runMaintenanceLoop(clock, pool, 1); - - CachedSession session3 = pool.getMultiplexedSessionWithFallback().get().get(); - assertNotEquals(session2.getName(), session3.getName()); - assertEquals(2, multiplexedSessionsRemoved.size()); - assertTrue(getNameOfSessionRemoved().contains(session2.getName())); - } - - @Test - public void - testMaintainMultiplexedSession_whenMultiplexedSessionNotStale_assertThatSessionIsNotRemoved() { - doAnswer( - invocation -> { - MultiplexedSessionInitializationConsumer consumer = - invocation.getArgument(0, MultiplexedSessionInitializationConsumer.class); - ReadContext mockContext = mock(ReadContext.class); - Timestamp timestamp = - Timestamp.ofTimeSecondsAndNanos( - Instant.ofEpochMilli(clock.currentTimeMillis.get()).getEpochSecond(), 0); - consumer.onSessionReady( - setupMockSession( - buildMockMultiplexedSession(client, mockContext, timestamp.toProto()), - mockContext)); - return null; - }) - .when(sessionClient) - .asyncCreateMultiplexedSession(any(MultiplexedSessionInitializationConsumer.class)); - SessionPool pool = createPool(); - - // Run one maintenance loop. - SessionFutureWrapper session1 = pool.getMultiplexedSessionWithFallback(); - runMaintenanceLoop(clock, pool, 1); - assertTrue(multiplexedSessionsRemoved.isEmpty()); - - // Advance clock by 4 days - clock.currentTimeMillis.addAndGet(Duration.ofDays(4).toMillis()); - // Run one maintenance loop. the first session would not be stale yet since it has now existed - // for less than 7 days. - runMaintenanceLoop(clock, pool, 1); - SessionFutureWrapper session2 = pool.getMultiplexedSessionWithFallback(); - assertTrue(multiplexedSessionsRemoved.isEmpty()); - assertEquals(session1.get().getName(), session2.get().getName()); - } - - @Test - public void - testMaintainMultiplexedSession_whenMultiplexedSessionCreationFailed_testRetryAfterDelay() { - doAnswer( - invocation -> { - MultiplexedSessionInitializationConsumer consumer = - invocation.getArgument(0, MultiplexedSessionInitializationConsumer.class); - ReadContext mockContext = mock(ReadContext.class); - Timestamp timestamp = - Timestamp.ofTimeSecondsAndNanos( - Instant.ofEpochMilli(clock.currentTimeMillis.get()).getEpochSecond(), 0); - consumer.onSessionReady( - setupMockSession( - buildMockMultiplexedSession(client, mockContext, timestamp.toProto()), - mockContext)); - return null; - }) - .when(sessionClient) - .asyncCreateMultiplexedSession(any(MultiplexedSessionInitializationConsumer.class)); - doAnswer( - invocation -> { - MultiplexedSessionMaintainerConsumer consumer = - invocation.getArgument(0, MultiplexedSessionMaintainerConsumer.class); - consumer.onSessionCreateFailure( - SpannerExceptionFactory.newSpannerException(ErrorCode.DEADLINE_EXCEEDED, ""), 1); - return null; - }) - .when(sessionClient) - .asyncCreateMultiplexedSession(any(MultiplexedSessionMaintainerConsumer.class)); - SessionPool pool = createPool(); - - // Advance clock by 8 days - clock.currentTimeMillis.addAndGet(Duration.ofDays(8).toMillis()); - - // Run one maintenance loop. Attempt replacing stale session should fail. - SessionFutureWrapper session1 = pool.getMultiplexedSessionWithFallback(); - runMaintenanceLoop(clock, pool, 1); - assertTrue(multiplexedSessionsRemoved.isEmpty()); - verify(sessionClient, times(1)) - .asyncCreateMultiplexedSession(any(MultiplexedSessionMaintainerConsumer.class)); - - // Advance clock by 10s and now mock session creation to be successful. - clock.currentTimeMillis.addAndGet(Duration.ofSeconds(10).toMillis()); - doAnswer( - invocation -> { - MultiplexedSessionMaintainerConsumer consumer = - invocation.getArgument(0, MultiplexedSessionMaintainerConsumer.class); - ReadContext mockContext = mock(ReadContext.class); - Timestamp timestamp = - Timestamp.ofTimeSecondsAndNanos( - Instant.ofEpochMilli(clock.currentTimeMillis.get()).getEpochSecond(), 0); - consumer.onSessionReady( - setupMockSession( - buildMockMultiplexedSession(client, mockContext, timestamp.toProto()), - mockContext)); - return null; - }) - .when(sessionClient) - .asyncCreateMultiplexedSession(any(MultiplexedSessionMaintainerConsumer.class)); - // Run one maintenance loop. Attempt should be ignored as it has not been 10 minutes since last - // attempt. - runMaintenanceLoop(clock, pool, 1); - SessionFutureWrapper session2 = pool.getMultiplexedSessionWithFallback(); - assertTrue(multiplexedSessionsRemoved.isEmpty()); - assertEquals(session1.get().getName(), session2.get().getName()); - verify(sessionClient, times(1)) - .asyncCreateMultiplexedSession(any(MultiplexedSessionMaintainerConsumer.class)); - - // Advance clock by 15 minutes - clock.currentTimeMillis.addAndGet(Duration.ofMinutes(15).toMillis()); - // Run one maintenance loop. Attempt should succeed since its already more than 10 minutes since - // the last attempt. - runMaintenanceLoop(clock, pool, 1); - SessionFutureWrapper session3 = pool.getMultiplexedSessionWithFallback(); - assertTrue(getNameOfSessionRemoved().contains(session1.get().get().getName())); - assertNotEquals(session1.get().getName(), session3.get().getName()); - verify(sessionClient, times(2)) - .asyncCreateMultiplexedSession(any(MultiplexedSessionMaintainerConsumer.class)); - } - - private SessionImpl setupMockSession(final SessionImpl session, final ReadContext mockContext) { - final ResultSet mockResult = mock(ResultSet.class); - when(mockContext.executeQuery(any(Statement.class))).thenAnswer(invocation -> mockResult); - when(mockResult.next()).thenReturn(true); - return session; - } - - private SessionPool createPool() { - // Allow sessions to be added to the head of the pool in all cases in this test, as it is - // otherwise impossible to know which session exactly is getting pinged at what point in time. - SessionPool pool = - SessionPool.createPool( - options, - new TestExecutorFactory(), - client.getSessionClient(db), - clock, - Position.FIRST, - new TraceWrapper(Tracing.getTracer(), OpenTelemetry.noop().getTracer(""), false), - OpenTelemetry.noop()); - pool.multiplexedSessionRemovedListener = - input -> { - multiplexedSessionsRemoved.add(input); - return null; - }; - return pool; - } - - Set getNameOfSessionRemoved() { - return multiplexedSessionsRemoved.stream() - .map(session -> session.getName()) - .collect(Collectors.toSet()); - } -} diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MultiplexedSessionPoolTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MultiplexedSessionPoolTest.java deleted file mode 100644 index fcad1ff22c..0000000000 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MultiplexedSessionPoolTest.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright 2024 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.cloud.spanner; - -import static com.google.common.truth.Truth.assertThat; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertThrows; -import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.mockito.MockitoAnnotations.initMocks; - -import com.google.cloud.spanner.SessionPool.MultiplexedSessionFuture; -import com.google.cloud.spanner.SessionPool.MultiplexedSessionInitializationConsumer; -import com.google.cloud.spanner.SessionPool.SessionFutureWrapper; -import com.google.cloud.spanner.SpannerImpl.ClosedException; -import io.opencensus.trace.Tracing; -import io.opentelemetry.api.OpenTelemetry; -import java.io.PrintWriter; -import java.io.StringWriter; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; -import org.mockito.Mock; -import org.threeten.bp.Duration; - -/** - * Tests for {@link com.google.cloud.spanner.SessionPool.MultiplexedSession} component within the - * {@link SessionPool} class. - */ -public class MultiplexedSessionPoolTest extends BaseSessionPoolTest { - - @Mock SpannerImpl client; - @Mock SessionClient sessionClient; - @Mock SpannerOptions spannerOptions; - private final DatabaseId db = DatabaseId.of("projects/p/instances/i/databases/unused"); - private final TraceWrapper tracer = - new TraceWrapper(Tracing.getTracer(), OpenTelemetry.noop().getTracer(""), false); - SessionPoolOptions options; - SessionPool pool; - - private SessionPool createPool() { - return SessionPool.createPool( - options, - new TestExecutorFactory(), - client.getSessionClient(db), - tracer, - OpenTelemetry.noop()); - } - - @BeforeClass - public static void checkUsesMultiplexedSessionPool() { - assumeTrue("Only run if the maintainer in the session pool is used", false); - } - - @Before - public void setUp() { - initMocks(this); - SpannerOptions.resetActiveTracingFramework(); - SpannerOptions.enableOpenTelemetryTraces(); - when(client.getOptions()).thenReturn(spannerOptions); - when(client.getSessionClient(db)).thenReturn(sessionClient); - when(sessionClient.getSpanner()).thenReturn(client); - when(spannerOptions.getNumChannels()).thenReturn(4); - when(spannerOptions.getDatabaseRole()).thenReturn("role"); - options = - SessionPoolOptions.newBuilder() - .setMinSessions(2) - .setMaxSessions(2) - .setUseMultiplexedSession(true) - .build(); - when(spannerOptions.getSessionPoolOptions()).thenReturn(options); - assumeTrue(options.getUseMultiplexedSession()); - } - - @Test - public void testGetMultiplexedSession_whenSessionInitializationSucceeded_assertSessionReturned() { - setupMockMultiplexedSessionCreation(); - - pool = createPool(); - assertTrue(pool.isValid()); - - // create 5 requests which require a session - for (int i = 0; i < 5; i++) { - // checking out a multiplexed session - SessionFutureWrapper multiplexedSessionFuture = pool.getMultiplexedSessionWithFallback(); - assertNotNull(multiplexedSessionFuture.get()); - } - verify(sessionClient, times(1)) - .asyncCreateMultiplexedSession(any(MultiplexedSessionInitializationConsumer.class)); - } - - @Test - public void testGetMultiplexedSession_whenClosedPool_assertSessionReturned() { - setupMockMultiplexedSessionCreation(); - - pool = createPool(); - assertTrue(pool.isValid()); - closePoolWithStacktrace(); - - // checking out a multiplexed session does not throw error even if pool is closed - MultiplexedSessionFuture multiplexedSessionFuture = - (MultiplexedSessionFuture) pool.getMultiplexedSessionWithFallback().get(); - assertNotNull(multiplexedSessionFuture); - - // checking out a regular session throws error. - IllegalStateException e = assertThrows(IllegalStateException.class, () -> pool.getSession()); - assertThat(e.getCause()).isInstanceOf(ClosedException.class); - StringWriter sw = new StringWriter(); - e.getCause().printStackTrace(new PrintWriter(sw)); - assertThat(sw.toString()).contains("closePoolWithStacktrace"); - } - - private void closePoolWithStacktrace() { - pool.closeAsync(new SpannerImpl.ClosedException()); - } - - @Test - public void testGetMultiplexedSession_whenSessionCreationFailed_assertErrorForWaiters() { - doAnswer( - invocation -> { - MultiplexedSessionInitializationConsumer consumer = - invocation.getArgument(0, MultiplexedSessionInitializationConsumer.class); - consumer.onSessionCreateFailure( - SpannerExceptionFactory.newSpannerException(ErrorCode.DEADLINE_EXCEEDED, ""), 1); - return null; - }) - .when(sessionClient) - .asyncCreateMultiplexedSession(any(MultiplexedSessionInitializationConsumer.class)); - options = - options - .toBuilder() - .setMinSessions(2) - .setUseMultiplexedSession(true) - .setAcquireSessionTimeout( - Duration.ofMillis(50)) // block for a max of 50 ms for session to be available - .build(); - pool = createPool(); - - // create 5 requests which require a session - for (int i = 0; i < 5; i++) { - SpannerException e = - assertThrows( - SpannerException.class, () -> pool.getMultiplexedSessionWithFallback().get().get()); - assertEquals(ErrorCode.DEADLINE_EXCEEDED, e.getErrorCode()); - } - // assert that all 5 requests failed with exception - assertEquals(0, pool.getNumWaiterTimeouts()); - assertEquals(0, pool.getNumberOfSessionsInPool()); - } - - private void setupMockMultiplexedSessionCreation() { - doAnswer( - invocation -> { - MultiplexedSessionInitializationConsumer consumer = - invocation.getArgument(0, MultiplexedSessionInitializationConsumer.class); - consumer.onSessionReady(mockSession()); - return null; - }) - .when(sessionClient) - .asyncCreateMultiplexedSession(any(MultiplexedSessionInitializationConsumer.class)); - } -} diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolTest.java index 8ffc4f21a1..564e2b97aa 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolTest.java @@ -64,7 +64,6 @@ import com.google.cloud.spanner.MetricRegistryTestUtils.PointWithFunction; import com.google.cloud.spanner.ReadContext.QueryAnalyzeMode; import com.google.cloud.spanner.SessionClient.SessionConsumer; -import com.google.cloud.spanner.SessionPool.MultiplexedSessionInitializationConsumer; import com.google.cloud.spanner.SessionPool.PooledSession; import com.google.cloud.spanner.SessionPool.PooledSessionFuture; import com.google.cloud.spanner.SessionPool.Position; @@ -2212,16 +2211,6 @@ public void testWaitOnMinSessionsWhenSessionsAreCreatedBeforeTimeout() { })) .when(sessionClient) .asyncBatchCreateSessions(Mockito.eq(1), Mockito.anyBoolean(), any(SessionConsumer.class)); - doAnswer( - invocation -> - executor.submit( - () -> { - MultiplexedSessionInitializationConsumer consumer = - invocation.getArgument(0, MultiplexedSessionInitializationConsumer.class); - consumer.onSessionReady(mockMultiplexedSession()); - })) - .when(sessionClient) - .asyncCreateMultiplexedSession(any(MultiplexedSessionInitializationConsumer.class)); pool = createPool(new FakeClock(), new FakeMetricRegistry(), SPANNER_DEFAULT_LABEL_VALUES); pool.maybeWaitOnMinSessions(); From c95d61b750794b9250640bf46216d01200e56328 Mon Sep 17 00:00:00 2001 From: Min Zhu Date: Wed, 31 Jul 2024 16:56:17 -0400 Subject: [PATCH 05/38] chore: setup 6.66.x lts branch (#3230) --- .github/release-please.yml | 4 ++++ .github/sync-repo-settings.yaml | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/.github/release-please.yml b/.github/release-please.yml index be8096d847..2853b1763c 100644 --- a/.github/release-please.yml +++ b/.github/release-please.yml @@ -38,3 +38,7 @@ branches: bumpMinorPreMajor: true handleGHRelease: true branch: 6.67.x + - releaseType: java-backport + bumpMinorPreMajor: true + handleGHRelease: true + branch: 6.66.x diff --git a/.github/sync-repo-settings.yaml b/.github/sync-repo-settings.yaml index d0bf28ee0f..7ab67b223e 100644 --- a/.github/sync-repo-settings.yaml +++ b/.github/sync-repo-settings.yaml @@ -140,6 +140,25 @@ branchProtectionRules: - checkstyle - compile (8) - compile (11) + - pattern: 6.66.x + isAdminEnforced: true + requiredApprovingReviewCount: 1 + requiresCodeOwnerReviews: true + requiresStrictStatusChecks: false + requiredStatusCheckContexts: + - dependencies (17) + - lint + - javadoc + - units (8) + - units (11) + - 'Kokoro - Test: Integration' + - 'Kokoro - Test: Integration with Multiplexed Sessions' + - cla/google + - checkstyle + - compile (8) + - compile (11) + - units-with-multiplexed-session (8) + - units-with-multiplexed-session (11) permissionRules: - team: yoshi-admins permission: admin From 86b306a4189483a5fd2746052bed817443630567 Mon Sep 17 00:00:00 2001 From: Sri Harsha CH <57220027+harshachinta@users.noreply.github.com> Date: Mon, 5 Aug 2024 10:49:43 +0530 Subject: [PATCH 06/38] feat(spanner): set manual affinity incase of gRPC-GCP extenstion (#3215) * feat(spanner): set manual affinity incase of gRPC-GCP extenstion * feat(spanner): convert channel hint to be bounded * feat(spanner): check if extension is enabled --- .../cloud/spanner/spi/v1/GapicSpannerRpc.java | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java index 2548e1fdc8..00ae72f169 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java @@ -56,6 +56,7 @@ import com.google.api.pathtemplate.PathTemplate; import com.google.cloud.RetryHelper; import com.google.cloud.RetryHelper.RetryHelperException; +import com.google.cloud.grpc.GcpManagedChannel; import com.google.cloud.grpc.GcpManagedChannelBuilder; import com.google.cloud.grpc.GcpManagedChannelOptions; import com.google.cloud.grpc.GcpManagedChannelOptions.GcpMetricsOptions; @@ -267,6 +268,8 @@ public class GapicSpannerRpc implements SpannerRpc { private static final ConcurrentMap ADMINISTRATIVE_REQUESTS_RATE_LIMITERS = new ConcurrentHashMap<>(); private final boolean leaderAwareRoutingEnabled; + private final int numChannels; + private final boolean isGrpcGcpExtensionEnabled; public static GapicSpannerRpc create(SpannerOptions options) { return new GapicSpannerRpc(options); @@ -318,6 +321,8 @@ public GapicSpannerRpc(final SpannerOptions options) { this.callCredentialsProvider = options.getCallCredentialsProvider(); this.compressorName = options.getCompressorName(); this.leaderAwareRoutingEnabled = options.isLeaderAwareRoutingEnabled(); + this.numChannels = options.getNumChannels(); + this.isGrpcGcpExtensionEnabled = options.isGrpcGcpExtensionEnabled(); if (initializeStubs) { // First check if SpannerOptions provides a TransportChannelProvider. Create one @@ -1960,7 +1965,20 @@ GrpcCallContext newCallContext( boolean routeToLeader) { GrpcCallContext context = GrpcCallContext.createDefault(); if (options != null) { - context = context.withChannelAffinity(Option.CHANNEL_HINT.getLong(options).intValue()); + if (this.isGrpcGcpExtensionEnabled) { + // Set channel affinity in gRPC-GCP. + // Compute bounded channel hint to prevent gRPC-GCP affinity map from getting unbounded. + int boundedChannelHint = Option.CHANNEL_HINT.getLong(options).intValue() % this.numChannels; + context = + context.withCallOptions( + context + .getCallOptions() + .withOption( + GcpManagedChannel.AFFINITY_KEY, String.valueOf(boundedChannelHint))); + } else { + // Set channel affinity in GAX. + context = context.withChannelAffinity(Option.CHANNEL_HINT.getLong(options).intValue()); + } } if (compressorName != null) { // This sets the compressor for Client -> Server. From d8891950a89ba06f1fe306e69537a5b65d994a52 Mon Sep 17 00:00:00 2001 From: cloud-java-bot <122572305+cloud-java-bot@users.noreply.github.com> Date: Mon, 5 Aug 2024 01:25:03 -0400 Subject: [PATCH 07/38] chore: Update generation configuration at Sat Aug 3 02:14:47 UTC 2024 (#3223) * chore: Update generation configuration at Tue Jul 23 02:15:33 UTC 2024 * chore: Update generation configuration at Wed Jul 24 02:15:30 UTC 2024 * chore: Update generation configuration at Thu Jul 25 02:15:36 UTC 2024 * chore: Update generation configuration at Fri Jul 26 02:15:26 UTC 2024 * chore: Update generation configuration at Sat Jul 27 02:14:35 UTC 2024 * chore: generate libraries at Sat Jul 27 02:15:05 UTC 2024 * chore: Update generation configuration at Tue Jul 30 02:15:43 UTC 2024 * chore: Update generation configuration at Wed Jul 31 02:03:43 UTC 2024 * chore: generate libraries at Wed Jul 31 02:04:08 UTC 2024 * chore: Update generation configuration at Thu Aug 1 02:19:28 UTC 2024 * chore: Update generation configuration at Fri Aug 2 02:15:43 UTC 2024 * chore: Update generation configuration at Sat Aug 3 02:14:47 UTC 2024 --- .repo-metadata.json | 2 +- README.md | 2 +- generation_config.yaml | 4 +- .../SpannerExecutorProxyStubSettings.java | 2 + .../reflect-config.json | 18 + .../v1/stub/DatabaseAdminStubSettings.java | 2 + .../v1/stub/InstanceAdminStubSettings.java | 2 + .../spanner/v1/stub/SpannerStubSettings.java | 2 + .../reflect-config.json | 18 + .../v1/DatabaseAdminClientHttpJsonTest.java | 44 + .../database/v1/DatabaseAdminClientTest.java | 36 + .../spanner/admin/database/v1/Backup.java | 928 ++++++++++++++++-- .../admin/database/v1/BackupOrBuilder.java | 129 +++ .../admin/database/v1/BackupProto.java | 217 ++-- .../admin/database/v1/BackupSchedule.java | 335 ++++++- .../database/v1/BackupScheduleOrBuilder.java | 39 + .../database/v1/BackupScheduleProto.java | 78 +- .../database/v1/IncrementalBackupSpec.java | 443 +++++++++ .../v1/IncrementalBackupSpecOrBuilder.java | 25 + .../spanner/admin/database/v1/backup.proto | 43 + .../admin/database/v1/backup_schedule.proto | 3 + 21 files changed, 2163 insertions(+), 209 deletions(-) create mode 100644 proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/IncrementalBackupSpec.java create mode 100644 proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/IncrementalBackupSpecOrBuilder.java diff --git a/.repo-metadata.json b/.repo-metadata.json index 5a0cd00cfe..7848b32f2b 100644 --- a/.repo-metadata.json +++ b/.repo-metadata.json @@ -5,7 +5,7 @@ "api_description": "is a fully managed, mission-critical, relational database service that offers transactional consistency at global scale, \\nschemas, SQL (ANSI 2011 with extensions), and automatic, synchronous replication \\nfor high availability.\\n\\nBe sure to activate the Cloud Spanner API on the Developer's Console to\\nuse Cloud Spanner from your project.", "client_documentation": "https://cloud.google.com/java/docs/reference/google-cloud-spanner/latest/history", "release_level": "stable", - "transport": "both", + "transport": "grpc", "language": "java", "repo": "googleapis/java-spanner", "repo_short": "java-spanner", diff --git a/README.md b/README.md index 95846aead8..0d4db4498e 100644 --- a/README.md +++ b/README.md @@ -621,7 +621,7 @@ To get help, follow the instructions in the [shared Troubleshooting document][tr ## Transport -Cloud Spanner uses both gRPC and HTTP/JSON for the transport layer. +Cloud Spanner uses gRPC for the transport layer. ## Supported Java Versions diff --git a/generation_config.yaml b/generation_config.yaml index 5db47f1db7..94e11368e5 100644 --- a/generation_config.yaml +++ b/generation_config.yaml @@ -1,5 +1,5 @@ -gapic_generator_version: 2.42.0 -googleapis_commitish: 19577edb4d439db98d2fb1f6f48f2e1b29fba099 +gapic_generator_version: 2.43.0 +googleapis_commitish: bc05924644a4bb93c0ac5973a07b83387a93b71f libraries_bom_version: 26.43.0 libraries: - api_shortname: spanner diff --git a/google-cloud-spanner-executor/src/main/java/com/google/cloud/spanner/executor/v1/stub/SpannerExecutorProxyStubSettings.java b/google-cloud-spanner-executor/src/main/java/com/google/cloud/spanner/executor/v1/stub/SpannerExecutorProxyStubSettings.java index 2b8c17ada9..88843026f4 100644 --- a/google-cloud-spanner-executor/src/main/java/com/google/cloud/spanner/executor/v1/stub/SpannerExecutorProxyStubSettings.java +++ b/google-cloud-spanner-executor/src/main/java/com/google/cloud/spanner/executor/v1/stub/SpannerExecutorProxyStubSettings.java @@ -17,6 +17,7 @@ package com.google.cloud.spanner.executor.v1.stub; import com.google.api.core.ApiFunction; +import com.google.api.core.ObsoleteApi; import com.google.api.gax.core.GaxProperties; import com.google.api.gax.core.GoogleCredentialsProvider; import com.google.api.gax.core.InstantiatingExecutorProvider; @@ -119,6 +120,7 @@ public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuild } /** Returns the default service endpoint. */ + @ObsoleteApi("Use getEndpoint() instead") public static String getDefaultEndpoint() { return "spanner-cloud-executor.googleapis.com:443"; } diff --git a/google-cloud-spanner-executor/src/main/resources/META-INF/native-image/com.google.cloud.spanner.executor.v1/reflect-config.json b/google-cloud-spanner-executor/src/main/resources/META-INF/native-image/com.google.cloud.spanner.executor.v1/reflect-config.json index f059459138..e28206a3de 100644 --- a/google-cloud-spanner-executor/src/main/resources/META-INF/native-image/com.google.cloud.spanner.executor.v1/reflect-config.json +++ b/google-cloud-spanner-executor/src/main/resources/META-INF/native-image/com.google.cloud.spanner.executor.v1/reflect-config.json @@ -2222,6 +2222,24 @@ "allDeclaredClasses": true, "allPublicClasses": true }, + { + "name": "com.google.spanner.admin.database.v1.IncrementalBackupSpec", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.spanner.admin.database.v1.IncrementalBackupSpec$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, { "name": "com.google.spanner.admin.database.v1.ListBackupOperationsRequest", "queryAllDeclaredConstructors": true, diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/stub/DatabaseAdminStubSettings.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/stub/DatabaseAdminStubSettings.java index 7ee7568722..2865fcd8d0 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/stub/DatabaseAdminStubSettings.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/stub/DatabaseAdminStubSettings.java @@ -26,6 +26,7 @@ import com.google.api.core.ApiFunction; import com.google.api.core.ApiFuture; import com.google.api.core.BetaApi; +import com.google.api.core.ObsoleteApi; import com.google.api.gax.core.GaxProperties; import com.google.api.gax.core.GoogleCredentialsProvider; import com.google.api.gax.core.InstantiatingExecutorProvider; @@ -774,6 +775,7 @@ public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuild } /** Returns the default service endpoint. */ + @ObsoleteApi("Use getEndpoint() instead") public static String getDefaultEndpoint() { return "spanner.googleapis.com:443"; } diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/instance/v1/stub/InstanceAdminStubSettings.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/instance/v1/stub/InstanceAdminStubSettings.java index 9a00b312c6..a74094a314 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/instance/v1/stub/InstanceAdminStubSettings.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/instance/v1/stub/InstanceAdminStubSettings.java @@ -25,6 +25,7 @@ import com.google.api.core.ApiFunction; import com.google.api.core.ApiFuture; import com.google.api.core.BetaApi; +import com.google.api.core.ObsoleteApi; import com.google.api.gax.core.GaxProperties; import com.google.api.gax.core.GoogleCredentialsProvider; import com.google.api.gax.core.InstantiatingExecutorProvider; @@ -738,6 +739,7 @@ public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuild } /** Returns the default service endpoint. */ + @ObsoleteApi("Use getEndpoint() instead") public static String getDefaultEndpoint() { return "spanner.googleapis.com:443"; } diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/v1/stub/SpannerStubSettings.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/v1/stub/SpannerStubSettings.java index db96f17542..fa6b86633b 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/v1/stub/SpannerStubSettings.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/v1/stub/SpannerStubSettings.java @@ -21,6 +21,7 @@ import com.google.api.core.ApiFunction; import com.google.api.core.ApiFuture; import com.google.api.core.BetaApi; +import com.google.api.core.ObsoleteApi; import com.google.api.gax.core.GaxProperties; import com.google.api.gax.core.GoogleCredentialsProvider; import com.google.api.gax.core.InstantiatingExecutorProvider; @@ -311,6 +312,7 @@ public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuild } /** Returns the default service endpoint. */ + @ObsoleteApi("Use getEndpoint() instead") public static String getDefaultEndpoint() { return "spanner.googleapis.com:443"; } diff --git a/google-cloud-spanner/src/main/resources/META-INF/native-image/com.google.cloud.spanner.admin.database.v1/reflect-config.json b/google-cloud-spanner/src/main/resources/META-INF/native-image/com.google.cloud.spanner.admin.database.v1/reflect-config.json index 51848a4129..37bd9977c1 100644 --- a/google-cloud-spanner/src/main/resources/META-INF/native-image/com.google.cloud.spanner.admin.database.v1/reflect-config.json +++ b/google-cloud-spanner/src/main/resources/META-INF/native-image/com.google.cloud.spanner.admin.database.v1/reflect-config.json @@ -2159,6 +2159,24 @@ "allDeclaredClasses": true, "allPublicClasses": true }, + { + "name": "com.google.spanner.admin.database.v1.IncrementalBackupSpec", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.spanner.admin.database.v1.IncrementalBackupSpec$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, { "name": "com.google.spanner.admin.database.v1.ListBackupOperationsRequest", "queryAllDeclaredConstructors": true, diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminClientHttpJsonTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminClientHttpJsonTest.java index 5e0d53da4c..b5a045b24a 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminClientHttpJsonTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminClientHttpJsonTest.java @@ -1086,6 +1086,8 @@ public void createBackupTest() throws Exception { .setName(BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]").toString()) .setCreateTime(Timestamp.newBuilder().build()) .setSizeBytes(-1796325715) + .setFreeableSizeBytes(1302251206) + .setExclusiveSizeBytes(-1085921554) .addAllReferencingDatabases(new ArrayList()) .setEncryptionInfo(EncryptionInfo.newBuilder().build()) .addAllEncryptionInformation(new ArrayList()) @@ -1093,6 +1095,8 @@ public void createBackupTest() throws Exception { .addAllReferencingBackups(new ArrayList()) .setMaxExpireTime(Timestamp.newBuilder().build()) .addAllBackupSchedules(new ArrayList()) + .setIncrementalBackupChainId("incrementalBackupChainId1926005216") + .setOldestVersionTime(Timestamp.newBuilder().build()) .build(); Operation resultOperation = Operation.newBuilder() @@ -1151,6 +1155,8 @@ public void createBackupTest2() throws Exception { .setName(BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]").toString()) .setCreateTime(Timestamp.newBuilder().build()) .setSizeBytes(-1796325715) + .setFreeableSizeBytes(1302251206) + .setExclusiveSizeBytes(-1085921554) .addAllReferencingDatabases(new ArrayList()) .setEncryptionInfo(EncryptionInfo.newBuilder().build()) .addAllEncryptionInformation(new ArrayList()) @@ -1158,6 +1164,8 @@ public void createBackupTest2() throws Exception { .addAllReferencingBackups(new ArrayList()) .setMaxExpireTime(Timestamp.newBuilder().build()) .addAllBackupSchedules(new ArrayList()) + .setIncrementalBackupChainId("incrementalBackupChainId1926005216") + .setOldestVersionTime(Timestamp.newBuilder().build()) .build(); Operation resultOperation = Operation.newBuilder() @@ -1216,6 +1224,8 @@ public void copyBackupTest() throws Exception { .setName(BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]").toString()) .setCreateTime(Timestamp.newBuilder().build()) .setSizeBytes(-1796325715) + .setFreeableSizeBytes(1302251206) + .setExclusiveSizeBytes(-1085921554) .addAllReferencingDatabases(new ArrayList()) .setEncryptionInfo(EncryptionInfo.newBuilder().build()) .addAllEncryptionInformation(new ArrayList()) @@ -1223,6 +1233,8 @@ public void copyBackupTest() throws Exception { .addAllReferencingBackups(new ArrayList()) .setMaxExpireTime(Timestamp.newBuilder().build()) .addAllBackupSchedules(new ArrayList()) + .setIncrementalBackupChainId("incrementalBackupChainId1926005216") + .setOldestVersionTime(Timestamp.newBuilder().build()) .build(); Operation resultOperation = Operation.newBuilder() @@ -1284,6 +1296,8 @@ public void copyBackupTest2() throws Exception { .setName(BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]").toString()) .setCreateTime(Timestamp.newBuilder().build()) .setSizeBytes(-1796325715) + .setFreeableSizeBytes(1302251206) + .setExclusiveSizeBytes(-1085921554) .addAllReferencingDatabases(new ArrayList()) .setEncryptionInfo(EncryptionInfo.newBuilder().build()) .addAllEncryptionInformation(new ArrayList()) @@ -1291,6 +1305,8 @@ public void copyBackupTest2() throws Exception { .addAllReferencingBackups(new ArrayList()) .setMaxExpireTime(Timestamp.newBuilder().build()) .addAllBackupSchedules(new ArrayList()) + .setIncrementalBackupChainId("incrementalBackupChainId1926005216") + .setOldestVersionTime(Timestamp.newBuilder().build()) .build(); Operation resultOperation = Operation.newBuilder() @@ -1352,6 +1368,8 @@ public void copyBackupTest3() throws Exception { .setName(BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]").toString()) .setCreateTime(Timestamp.newBuilder().build()) .setSizeBytes(-1796325715) + .setFreeableSizeBytes(1302251206) + .setExclusiveSizeBytes(-1085921554) .addAllReferencingDatabases(new ArrayList()) .setEncryptionInfo(EncryptionInfo.newBuilder().build()) .addAllEncryptionInformation(new ArrayList()) @@ -1359,6 +1377,8 @@ public void copyBackupTest3() throws Exception { .addAllReferencingBackups(new ArrayList()) .setMaxExpireTime(Timestamp.newBuilder().build()) .addAllBackupSchedules(new ArrayList()) + .setIncrementalBackupChainId("incrementalBackupChainId1926005216") + .setOldestVersionTime(Timestamp.newBuilder().build()) .build(); Operation resultOperation = Operation.newBuilder() @@ -1420,6 +1440,8 @@ public void copyBackupTest4() throws Exception { .setName(BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]").toString()) .setCreateTime(Timestamp.newBuilder().build()) .setSizeBytes(-1796325715) + .setFreeableSizeBytes(1302251206) + .setExclusiveSizeBytes(-1085921554) .addAllReferencingDatabases(new ArrayList()) .setEncryptionInfo(EncryptionInfo.newBuilder().build()) .addAllEncryptionInformation(new ArrayList()) @@ -1427,6 +1449,8 @@ public void copyBackupTest4() throws Exception { .addAllReferencingBackups(new ArrayList()) .setMaxExpireTime(Timestamp.newBuilder().build()) .addAllBackupSchedules(new ArrayList()) + .setIncrementalBackupChainId("incrementalBackupChainId1926005216") + .setOldestVersionTime(Timestamp.newBuilder().build()) .build(); Operation resultOperation = Operation.newBuilder() @@ -1488,6 +1512,8 @@ public void getBackupTest() throws Exception { .setName(BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]").toString()) .setCreateTime(Timestamp.newBuilder().build()) .setSizeBytes(-1796325715) + .setFreeableSizeBytes(1302251206) + .setExclusiveSizeBytes(-1085921554) .addAllReferencingDatabases(new ArrayList()) .setEncryptionInfo(EncryptionInfo.newBuilder().build()) .addAllEncryptionInformation(new ArrayList()) @@ -1495,6 +1521,8 @@ public void getBackupTest() throws Exception { .addAllReferencingBackups(new ArrayList()) .setMaxExpireTime(Timestamp.newBuilder().build()) .addAllBackupSchedules(new ArrayList()) + .setIncrementalBackupChainId("incrementalBackupChainId1926005216") + .setOldestVersionTime(Timestamp.newBuilder().build()) .build(); mockService.addResponse(expectedResponse); @@ -1544,6 +1572,8 @@ public void getBackupTest2() throws Exception { .setName(BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]").toString()) .setCreateTime(Timestamp.newBuilder().build()) .setSizeBytes(-1796325715) + .setFreeableSizeBytes(1302251206) + .setExclusiveSizeBytes(-1085921554) .addAllReferencingDatabases(new ArrayList()) .setEncryptionInfo(EncryptionInfo.newBuilder().build()) .addAllEncryptionInformation(new ArrayList()) @@ -1551,6 +1581,8 @@ public void getBackupTest2() throws Exception { .addAllReferencingBackups(new ArrayList()) .setMaxExpireTime(Timestamp.newBuilder().build()) .addAllBackupSchedules(new ArrayList()) + .setIncrementalBackupChainId("incrementalBackupChainId1926005216") + .setOldestVersionTime(Timestamp.newBuilder().build()) .build(); mockService.addResponse(expectedResponse); @@ -1600,6 +1632,8 @@ public void updateBackupTest() throws Exception { .setName(BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]").toString()) .setCreateTime(Timestamp.newBuilder().build()) .setSizeBytes(-1796325715) + .setFreeableSizeBytes(1302251206) + .setExclusiveSizeBytes(-1085921554) .addAllReferencingDatabases(new ArrayList()) .setEncryptionInfo(EncryptionInfo.newBuilder().build()) .addAllEncryptionInformation(new ArrayList()) @@ -1607,6 +1641,8 @@ public void updateBackupTest() throws Exception { .addAllReferencingBackups(new ArrayList()) .setMaxExpireTime(Timestamp.newBuilder().build()) .addAllBackupSchedules(new ArrayList()) + .setIncrementalBackupChainId("incrementalBackupChainId1926005216") + .setOldestVersionTime(Timestamp.newBuilder().build()) .build(); mockService.addResponse(expectedResponse); @@ -1618,6 +1654,8 @@ public void updateBackupTest() throws Exception { .setName(BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]").toString()) .setCreateTime(Timestamp.newBuilder().build()) .setSizeBytes(-1796325715) + .setFreeableSizeBytes(1302251206) + .setExclusiveSizeBytes(-1085921554) .addAllReferencingDatabases(new ArrayList()) .setEncryptionInfo(EncryptionInfo.newBuilder().build()) .addAllEncryptionInformation(new ArrayList()) @@ -1625,6 +1663,8 @@ public void updateBackupTest() throws Exception { .addAllReferencingBackups(new ArrayList()) .setMaxExpireTime(Timestamp.newBuilder().build()) .addAllBackupSchedules(new ArrayList()) + .setIncrementalBackupChainId("incrementalBackupChainId1926005216") + .setOldestVersionTime(Timestamp.newBuilder().build()) .build(); FieldMask updateMask = FieldMask.newBuilder().build(); @@ -1662,6 +1702,8 @@ public void updateBackupExceptionTest() throws Exception { .setName(BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]").toString()) .setCreateTime(Timestamp.newBuilder().build()) .setSizeBytes(-1796325715) + .setFreeableSizeBytes(1302251206) + .setExclusiveSizeBytes(-1085921554) .addAllReferencingDatabases(new ArrayList()) .setEncryptionInfo(EncryptionInfo.newBuilder().build()) .addAllEncryptionInformation(new ArrayList()) @@ -1669,6 +1711,8 @@ public void updateBackupExceptionTest() throws Exception { .addAllReferencingBackups(new ArrayList()) .setMaxExpireTime(Timestamp.newBuilder().build()) .addAllBackupSchedules(new ArrayList()) + .setIncrementalBackupChainId("incrementalBackupChainId1926005216") + .setOldestVersionTime(Timestamp.newBuilder().build()) .build(); FieldMask updateMask = FieldMask.newBuilder().build(); client.updateBackup(backup, updateMask); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminClientTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminClientTest.java index 469c0f53a1..a4de864ee6 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminClientTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminClientTest.java @@ -999,6 +999,8 @@ public void createBackupTest() throws Exception { .setName(BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]").toString()) .setCreateTime(Timestamp.newBuilder().build()) .setSizeBytes(-1796325715) + .setFreeableSizeBytes(1302251206) + .setExclusiveSizeBytes(-1085921554) .addAllReferencingDatabases(new ArrayList()) .setEncryptionInfo(EncryptionInfo.newBuilder().build()) .addAllEncryptionInformation(new ArrayList()) @@ -1006,6 +1008,8 @@ public void createBackupTest() throws Exception { .addAllReferencingBackups(new ArrayList()) .setMaxExpireTime(Timestamp.newBuilder().build()) .addAllBackupSchedules(new ArrayList()) + .setIncrementalBackupChainId("incrementalBackupChainId1926005216") + .setOldestVersionTime(Timestamp.newBuilder().build()) .build(); Operation resultOperation = Operation.newBuilder() @@ -1063,6 +1067,8 @@ public void createBackupTest2() throws Exception { .setName(BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]").toString()) .setCreateTime(Timestamp.newBuilder().build()) .setSizeBytes(-1796325715) + .setFreeableSizeBytes(1302251206) + .setExclusiveSizeBytes(-1085921554) .addAllReferencingDatabases(new ArrayList()) .setEncryptionInfo(EncryptionInfo.newBuilder().build()) .addAllEncryptionInformation(new ArrayList()) @@ -1070,6 +1076,8 @@ public void createBackupTest2() throws Exception { .addAllReferencingBackups(new ArrayList()) .setMaxExpireTime(Timestamp.newBuilder().build()) .addAllBackupSchedules(new ArrayList()) + .setIncrementalBackupChainId("incrementalBackupChainId1926005216") + .setOldestVersionTime(Timestamp.newBuilder().build()) .build(); Operation resultOperation = Operation.newBuilder() @@ -1127,6 +1135,8 @@ public void copyBackupTest() throws Exception { .setName(BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]").toString()) .setCreateTime(Timestamp.newBuilder().build()) .setSizeBytes(-1796325715) + .setFreeableSizeBytes(1302251206) + .setExclusiveSizeBytes(-1085921554) .addAllReferencingDatabases(new ArrayList()) .setEncryptionInfo(EncryptionInfo.newBuilder().build()) .addAllEncryptionInformation(new ArrayList()) @@ -1134,6 +1144,8 @@ public void copyBackupTest() throws Exception { .addAllReferencingBackups(new ArrayList()) .setMaxExpireTime(Timestamp.newBuilder().build()) .addAllBackupSchedules(new ArrayList()) + .setIncrementalBackupChainId("incrementalBackupChainId1926005216") + .setOldestVersionTime(Timestamp.newBuilder().build()) .build(); Operation resultOperation = Operation.newBuilder() @@ -1195,6 +1207,8 @@ public void copyBackupTest2() throws Exception { .setName(BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]").toString()) .setCreateTime(Timestamp.newBuilder().build()) .setSizeBytes(-1796325715) + .setFreeableSizeBytes(1302251206) + .setExclusiveSizeBytes(-1085921554) .addAllReferencingDatabases(new ArrayList()) .setEncryptionInfo(EncryptionInfo.newBuilder().build()) .addAllEncryptionInformation(new ArrayList()) @@ -1202,6 +1216,8 @@ public void copyBackupTest2() throws Exception { .addAllReferencingBackups(new ArrayList()) .setMaxExpireTime(Timestamp.newBuilder().build()) .addAllBackupSchedules(new ArrayList()) + .setIncrementalBackupChainId("incrementalBackupChainId1926005216") + .setOldestVersionTime(Timestamp.newBuilder().build()) .build(); Operation resultOperation = Operation.newBuilder() @@ -1263,6 +1279,8 @@ public void copyBackupTest3() throws Exception { .setName(BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]").toString()) .setCreateTime(Timestamp.newBuilder().build()) .setSizeBytes(-1796325715) + .setFreeableSizeBytes(1302251206) + .setExclusiveSizeBytes(-1085921554) .addAllReferencingDatabases(new ArrayList()) .setEncryptionInfo(EncryptionInfo.newBuilder().build()) .addAllEncryptionInformation(new ArrayList()) @@ -1270,6 +1288,8 @@ public void copyBackupTest3() throws Exception { .addAllReferencingBackups(new ArrayList()) .setMaxExpireTime(Timestamp.newBuilder().build()) .addAllBackupSchedules(new ArrayList()) + .setIncrementalBackupChainId("incrementalBackupChainId1926005216") + .setOldestVersionTime(Timestamp.newBuilder().build()) .build(); Operation resultOperation = Operation.newBuilder() @@ -1331,6 +1351,8 @@ public void copyBackupTest4() throws Exception { .setName(BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]").toString()) .setCreateTime(Timestamp.newBuilder().build()) .setSizeBytes(-1796325715) + .setFreeableSizeBytes(1302251206) + .setExclusiveSizeBytes(-1085921554) .addAllReferencingDatabases(new ArrayList()) .setEncryptionInfo(EncryptionInfo.newBuilder().build()) .addAllEncryptionInformation(new ArrayList()) @@ -1338,6 +1360,8 @@ public void copyBackupTest4() throws Exception { .addAllReferencingBackups(new ArrayList()) .setMaxExpireTime(Timestamp.newBuilder().build()) .addAllBackupSchedules(new ArrayList()) + .setIncrementalBackupChainId("incrementalBackupChainId1926005216") + .setOldestVersionTime(Timestamp.newBuilder().build()) .build(); Operation resultOperation = Operation.newBuilder() @@ -1399,6 +1423,8 @@ public void getBackupTest() throws Exception { .setName(BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]").toString()) .setCreateTime(Timestamp.newBuilder().build()) .setSizeBytes(-1796325715) + .setFreeableSizeBytes(1302251206) + .setExclusiveSizeBytes(-1085921554) .addAllReferencingDatabases(new ArrayList()) .setEncryptionInfo(EncryptionInfo.newBuilder().build()) .addAllEncryptionInformation(new ArrayList()) @@ -1406,6 +1432,8 @@ public void getBackupTest() throws Exception { .addAllReferencingBackups(new ArrayList()) .setMaxExpireTime(Timestamp.newBuilder().build()) .addAllBackupSchedules(new ArrayList()) + .setIncrementalBackupChainId("incrementalBackupChainId1926005216") + .setOldestVersionTime(Timestamp.newBuilder().build()) .build(); mockDatabaseAdmin.addResponse(expectedResponse); @@ -1449,6 +1477,8 @@ public void getBackupTest2() throws Exception { .setName(BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]").toString()) .setCreateTime(Timestamp.newBuilder().build()) .setSizeBytes(-1796325715) + .setFreeableSizeBytes(1302251206) + .setExclusiveSizeBytes(-1085921554) .addAllReferencingDatabases(new ArrayList()) .setEncryptionInfo(EncryptionInfo.newBuilder().build()) .addAllEncryptionInformation(new ArrayList()) @@ -1456,6 +1486,8 @@ public void getBackupTest2() throws Exception { .addAllReferencingBackups(new ArrayList()) .setMaxExpireTime(Timestamp.newBuilder().build()) .addAllBackupSchedules(new ArrayList()) + .setIncrementalBackupChainId("incrementalBackupChainId1926005216") + .setOldestVersionTime(Timestamp.newBuilder().build()) .build(); mockDatabaseAdmin.addResponse(expectedResponse); @@ -1499,6 +1531,8 @@ public void updateBackupTest() throws Exception { .setName(BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]").toString()) .setCreateTime(Timestamp.newBuilder().build()) .setSizeBytes(-1796325715) + .setFreeableSizeBytes(1302251206) + .setExclusiveSizeBytes(-1085921554) .addAllReferencingDatabases(new ArrayList()) .setEncryptionInfo(EncryptionInfo.newBuilder().build()) .addAllEncryptionInformation(new ArrayList()) @@ -1506,6 +1540,8 @@ public void updateBackupTest() throws Exception { .addAllReferencingBackups(new ArrayList()) .setMaxExpireTime(Timestamp.newBuilder().build()) .addAllBackupSchedules(new ArrayList()) + .setIncrementalBackupChainId("incrementalBackupChainId1926005216") + .setOldestVersionTime(Timestamp.newBuilder().build()) .build(); mockDatabaseAdmin.addResponse(expectedResponse); diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/Backup.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/Backup.java index 813c859b36..96dc6990ec 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/Backup.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/Backup.java @@ -47,6 +47,7 @@ private Backup() { databaseDialect_ = 0; referencingBackups_ = com.google.protobuf.LazyStringArrayList.emptyList(); backupSchedules_ = com.google.protobuf.LazyStringArrayList.emptyList(); + incrementalBackupChainId_ = ""; } @java.lang.Override @@ -565,6 +566,54 @@ public long getSizeBytes() { return sizeBytes_; } + public static final int FREEABLE_SIZE_BYTES_FIELD_NUMBER = 15; + private long freeableSizeBytes_ = 0L; + /** + * + * + *

+   * Output only. The number of bytes that will be freed by deleting this
+   * backup. This value will be zero if, for example, this backup is part of an
+   * incremental backup chain and younger backups in the chain require that we
+   * keep its data. For backups not in an incremental backup chain, this is
+   * always the size of the backup. This value may change if backups on the same
+   * chain get created, deleted or expired.
+   * 
+ * + * int64 freeable_size_bytes = 15 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + * @return The freeableSizeBytes. + */ + @java.lang.Override + public long getFreeableSizeBytes() { + return freeableSizeBytes_; + } + + public static final int EXCLUSIVE_SIZE_BYTES_FIELD_NUMBER = 16; + private long exclusiveSizeBytes_ = 0L; + /** + * + * + *
+   * Output only. For a backup in an incremental backup chain, this is the
+   * storage space needed to keep the data that has changed since the previous
+   * backup. For all other backups, this is always the size of the backup. This
+   * value may change if backups on the same chain get deleted or expired.
+   *
+   * This field can be used to calculate the total storage space used by a set
+   * of backups. For example, the total space used by all backups of a database
+   * can be computed by summing up this field.
+   * 
+ * + * int64 exclusive_size_bytes = 16 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + * @return The exclusiveSizeBytes. + */ + @java.lang.Override + public long getExclusiveSizeBytes() { + return exclusiveSizeBytes_; + } + public static final int STATE_FIELD_NUMBER = 6; private int state_ = 0; /** @@ -1170,6 +1219,138 @@ public com.google.protobuf.ByteString getBackupSchedulesBytes(int index) { return backupSchedules_.getByteString(index); } + public static final int INCREMENTAL_BACKUP_CHAIN_ID_FIELD_NUMBER = 17; + + @SuppressWarnings("serial") + private volatile java.lang.Object incrementalBackupChainId_ = ""; + /** + * + * + *
+   * Output only. Populated only for backups in an incremental backup chain.
+   * Backups share the same chain id if and only if they belong to the same
+   * incremental backup chain. Use this field to determine which backups are
+   * part of the same incremental backup chain. The ordering of backups in the
+   * chain can be determined by ordering the backup `version_time`.
+   * 
+ * + * string incremental_backup_chain_id = 17 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + * + * @return The incrementalBackupChainId. + */ + @java.lang.Override + public java.lang.String getIncrementalBackupChainId() { + java.lang.Object ref = incrementalBackupChainId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + incrementalBackupChainId_ = s; + return s; + } + } + /** + * + * + *
+   * Output only. Populated only for backups in an incremental backup chain.
+   * Backups share the same chain id if and only if they belong to the same
+   * incremental backup chain. Use this field to determine which backups are
+   * part of the same incremental backup chain. The ordering of backups in the
+   * chain can be determined by ordering the backup `version_time`.
+   * 
+ * + * string incremental_backup_chain_id = 17 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + * + * @return The bytes for incrementalBackupChainId. + */ + @java.lang.Override + public com.google.protobuf.ByteString getIncrementalBackupChainIdBytes() { + java.lang.Object ref = incrementalBackupChainId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8((java.lang.String) ref); + incrementalBackupChainId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int OLDEST_VERSION_TIME_FIELD_NUMBER = 18; + private com.google.protobuf.Timestamp oldestVersionTime_; + /** + * + * + *
+   * Output only. Data deleted at a time older than this is guaranteed not to be
+   * retained in order to support this backup. For a backup in an incremental
+   * backup chain, this is the version time of the oldest backup that exists or
+   * ever existed in the chain. For all other backups, this is the version time
+   * of the backup. This field can be used to understand what data is being
+   * retained by the backup system.
+   * 
+ * + * + * .google.protobuf.Timestamp oldest_version_time = 18 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + * + * @return Whether the oldestVersionTime field is set. + */ + @java.lang.Override + public boolean hasOldestVersionTime() { + return ((bitField0_ & 0x00000020) != 0); + } + /** + * + * + *
+   * Output only. Data deleted at a time older than this is guaranteed not to be
+   * retained in order to support this backup. For a backup in an incremental
+   * backup chain, this is the version time of the oldest backup that exists or
+   * ever existed in the chain. For all other backups, this is the version time
+   * of the backup. This field can be used to understand what data is being
+   * retained by the backup system.
+   * 
+ * + * + * .google.protobuf.Timestamp oldest_version_time = 18 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + * + * @return The oldestVersionTime. + */ + @java.lang.Override + public com.google.protobuf.Timestamp getOldestVersionTime() { + return oldestVersionTime_ == null + ? com.google.protobuf.Timestamp.getDefaultInstance() + : oldestVersionTime_; + } + /** + * + * + *
+   * Output only. Data deleted at a time older than this is guaranteed not to be
+   * retained in order to support this backup. For a backup in an incremental
+   * backup chain, this is the version time of the oldest backup that exists or
+   * ever existed in the chain. For all other backups, this is the version time
+   * of the backup. This field can be used to understand what data is being
+   * retained by the backup system.
+   * 
+ * + * + * .google.protobuf.Timestamp oldest_version_time = 18 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + */ + @java.lang.Override + public com.google.protobuf.TimestampOrBuilder getOldestVersionTimeOrBuilder() { + return oldestVersionTime_ == null + ? com.google.protobuf.Timestamp.getDefaultInstance() + : oldestVersionTime_; + } + private byte memoizedIsInitialized = -1; @java.lang.Override @@ -1229,6 +1410,18 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io for (int i = 0; i < backupSchedules_.size(); i++) { com.google.protobuf.GeneratedMessageV3.writeString(output, 14, backupSchedules_.getRaw(i)); } + if (freeableSizeBytes_ != 0L) { + output.writeInt64(15, freeableSizeBytes_); + } + if (exclusiveSizeBytes_ != 0L) { + output.writeInt64(16, exclusiveSizeBytes_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(incrementalBackupChainId_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 17, incrementalBackupChainId_); + } + if (((bitField0_ & 0x00000020) != 0)) { + output.writeMessage(18, getOldestVersionTime()); + } getUnknownFields().writeTo(output); } @@ -1299,6 +1492,19 @@ public int getSerializedSize() { size += dataSize; size += 1 * getBackupSchedulesList().size(); } + if (freeableSizeBytes_ != 0L) { + size += com.google.protobuf.CodedOutputStream.computeInt64Size(15, freeableSizeBytes_); + } + if (exclusiveSizeBytes_ != 0L) { + size += com.google.protobuf.CodedOutputStream.computeInt64Size(16, exclusiveSizeBytes_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(incrementalBackupChainId_)) { + size += + com.google.protobuf.GeneratedMessageV3.computeStringSize(17, incrementalBackupChainId_); + } + if (((bitField0_ & 0x00000020) != 0)) { + size += com.google.protobuf.CodedOutputStream.computeMessageSize(18, getOldestVersionTime()); + } size += getUnknownFields().getSerializedSize(); memoizedSize = size; return size; @@ -1330,6 +1536,8 @@ public boolean equals(final java.lang.Object obj) { if (!getCreateTime().equals(other.getCreateTime())) return false; } if (getSizeBytes() != other.getSizeBytes()) return false; + if (getFreeableSizeBytes() != other.getFreeableSizeBytes()) return false; + if (getExclusiveSizeBytes() != other.getExclusiveSizeBytes()) return false; if (state_ != other.state_) return false; if (!getReferencingDatabasesList().equals(other.getReferencingDatabasesList())) return false; if (hasEncryptionInfo() != other.hasEncryptionInfo()) return false; @@ -1344,6 +1552,11 @@ public boolean equals(final java.lang.Object obj) { if (!getMaxExpireTime().equals(other.getMaxExpireTime())) return false; } if (!getBackupSchedulesList().equals(other.getBackupSchedulesList())) return false; + if (!getIncrementalBackupChainId().equals(other.getIncrementalBackupChainId())) return false; + if (hasOldestVersionTime() != other.hasOldestVersionTime()) return false; + if (hasOldestVersionTime()) { + if (!getOldestVersionTime().equals(other.getOldestVersionTime())) return false; + } if (!getUnknownFields().equals(other.getUnknownFields())) return false; return true; } @@ -1373,6 +1586,10 @@ public int hashCode() { } hash = (37 * hash) + SIZE_BYTES_FIELD_NUMBER; hash = (53 * hash) + com.google.protobuf.Internal.hashLong(getSizeBytes()); + hash = (37 * hash) + FREEABLE_SIZE_BYTES_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashLong(getFreeableSizeBytes()); + hash = (37 * hash) + EXCLUSIVE_SIZE_BYTES_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashLong(getExclusiveSizeBytes()); hash = (37 * hash) + STATE_FIELD_NUMBER; hash = (53 * hash) + state_; if (getReferencingDatabasesCount() > 0) { @@ -1401,6 +1618,12 @@ public int hashCode() { hash = (37 * hash) + BACKUP_SCHEDULES_FIELD_NUMBER; hash = (53 * hash) + getBackupSchedulesList().hashCode(); } + hash = (37 * hash) + INCREMENTAL_BACKUP_CHAIN_ID_FIELD_NUMBER; + hash = (53 * hash) + getIncrementalBackupChainId().hashCode(); + if (hasOldestVersionTime()) { + hash = (37 * hash) + OLDEST_VERSION_TIME_FIELD_NUMBER; + hash = (53 * hash) + getOldestVersionTime().hashCode(); + } hash = (29 * hash) + getUnknownFields().hashCode(); memoizedHashCode = hash; return hash; @@ -1547,6 +1770,7 @@ private void maybeForceBuilderInitialization() { getEncryptionInfoFieldBuilder(); getEncryptionInformationFieldBuilder(); getMaxExpireTimeFieldBuilder(); + getOldestVersionTimeFieldBuilder(); } } @@ -1572,6 +1796,8 @@ public Builder clear() { createTimeBuilder_ = null; } sizeBytes_ = 0L; + freeableSizeBytes_ = 0L; + exclusiveSizeBytes_ = 0L; state_ = 0; referencingDatabases_ = com.google.protobuf.LazyStringArrayList.emptyList(); encryptionInfo_ = null; @@ -1585,7 +1811,7 @@ public Builder clear() { encryptionInformation_ = null; encryptionInformationBuilder_.clear(); } - bitField0_ = (bitField0_ & ~0x00000200); + bitField0_ = (bitField0_ & ~0x00000800); databaseDialect_ = 0; referencingBackups_ = com.google.protobuf.LazyStringArrayList.emptyList(); maxExpireTime_ = null; @@ -1594,6 +1820,12 @@ public Builder clear() { maxExpireTimeBuilder_ = null; } backupSchedules_ = com.google.protobuf.LazyStringArrayList.emptyList(); + incrementalBackupChainId_ = ""; + oldestVersionTime_ = null; + if (oldestVersionTimeBuilder_ != null) { + oldestVersionTimeBuilder_.dispose(); + oldestVersionTimeBuilder_ = null; + } return this; } @@ -1631,9 +1863,9 @@ public com.google.spanner.admin.database.v1.Backup buildPartial() { private void buildPartialRepeatedFields(com.google.spanner.admin.database.v1.Backup result) { if (encryptionInformationBuilder_ == null) { - if (((bitField0_ & 0x00000200) != 0)) { + if (((bitField0_ & 0x00000800) != 0)) { encryptionInformation_ = java.util.Collections.unmodifiableList(encryptionInformation_); - bitField0_ = (bitField0_ & ~0x00000200); + bitField0_ = (bitField0_ & ~0x00000800); } result.encryptionInformation_ = encryptionInformation_; } else { @@ -1667,33 +1899,49 @@ private void buildPartial0(com.google.spanner.admin.database.v1.Backup result) { result.sizeBytes_ = sizeBytes_; } if (((from_bitField0_ & 0x00000040) != 0)) { - result.state_ = state_; + result.freeableSizeBytes_ = freeableSizeBytes_; } if (((from_bitField0_ & 0x00000080) != 0)) { + result.exclusiveSizeBytes_ = exclusiveSizeBytes_; + } + if (((from_bitField0_ & 0x00000100) != 0)) { + result.state_ = state_; + } + if (((from_bitField0_ & 0x00000200) != 0)) { referencingDatabases_.makeImmutable(); result.referencingDatabases_ = referencingDatabases_; } - if (((from_bitField0_ & 0x00000100) != 0)) { + if (((from_bitField0_ & 0x00000400) != 0)) { result.encryptionInfo_ = encryptionInfoBuilder_ == null ? encryptionInfo_ : encryptionInfoBuilder_.build(); to_bitField0_ |= 0x00000008; } - if (((from_bitField0_ & 0x00000400) != 0)) { + if (((from_bitField0_ & 0x00001000) != 0)) { result.databaseDialect_ = databaseDialect_; } - if (((from_bitField0_ & 0x00000800) != 0)) { + if (((from_bitField0_ & 0x00002000) != 0)) { referencingBackups_.makeImmutable(); result.referencingBackups_ = referencingBackups_; } - if (((from_bitField0_ & 0x00001000) != 0)) { + if (((from_bitField0_ & 0x00004000) != 0)) { result.maxExpireTime_ = maxExpireTimeBuilder_ == null ? maxExpireTime_ : maxExpireTimeBuilder_.build(); to_bitField0_ |= 0x00000010; } - if (((from_bitField0_ & 0x00002000) != 0)) { + if (((from_bitField0_ & 0x00008000) != 0)) { backupSchedules_.makeImmutable(); result.backupSchedules_ = backupSchedules_; } + if (((from_bitField0_ & 0x00010000) != 0)) { + result.incrementalBackupChainId_ = incrementalBackupChainId_; + } + if (((from_bitField0_ & 0x00020000) != 0)) { + result.oldestVersionTime_ = + oldestVersionTimeBuilder_ == null + ? oldestVersionTime_ + : oldestVersionTimeBuilder_.build(); + to_bitField0_ |= 0x00000020; + } result.bitField0_ |= to_bitField0_; } @@ -1764,13 +2012,19 @@ public Builder mergeFrom(com.google.spanner.admin.database.v1.Backup other) { if (other.getSizeBytes() != 0L) { setSizeBytes(other.getSizeBytes()); } + if (other.getFreeableSizeBytes() != 0L) { + setFreeableSizeBytes(other.getFreeableSizeBytes()); + } + if (other.getExclusiveSizeBytes() != 0L) { + setExclusiveSizeBytes(other.getExclusiveSizeBytes()); + } if (other.state_ != 0) { setStateValue(other.getStateValue()); } if (!other.referencingDatabases_.isEmpty()) { if (referencingDatabases_.isEmpty()) { referencingDatabases_ = other.referencingDatabases_; - bitField0_ |= 0x00000080; + bitField0_ |= 0x00000200; } else { ensureReferencingDatabasesIsMutable(); referencingDatabases_.addAll(other.referencingDatabases_); @@ -1784,7 +2038,7 @@ public Builder mergeFrom(com.google.spanner.admin.database.v1.Backup other) { if (!other.encryptionInformation_.isEmpty()) { if (encryptionInformation_.isEmpty()) { encryptionInformation_ = other.encryptionInformation_; - bitField0_ = (bitField0_ & ~0x00000200); + bitField0_ = (bitField0_ & ~0x00000800); } else { ensureEncryptionInformationIsMutable(); encryptionInformation_.addAll(other.encryptionInformation_); @@ -1797,7 +2051,7 @@ public Builder mergeFrom(com.google.spanner.admin.database.v1.Backup other) { encryptionInformationBuilder_.dispose(); encryptionInformationBuilder_ = null; encryptionInformation_ = other.encryptionInformation_; - bitField0_ = (bitField0_ & ~0x00000200); + bitField0_ = (bitField0_ & ~0x00000800); encryptionInformationBuilder_ = com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ? getEncryptionInformationFieldBuilder() @@ -1813,7 +2067,7 @@ public Builder mergeFrom(com.google.spanner.admin.database.v1.Backup other) { if (!other.referencingBackups_.isEmpty()) { if (referencingBackups_.isEmpty()) { referencingBackups_ = other.referencingBackups_; - bitField0_ |= 0x00000800; + bitField0_ |= 0x00002000; } else { ensureReferencingBackupsIsMutable(); referencingBackups_.addAll(other.referencingBackups_); @@ -1826,13 +2080,21 @@ public Builder mergeFrom(com.google.spanner.admin.database.v1.Backup other) { if (!other.backupSchedules_.isEmpty()) { if (backupSchedules_.isEmpty()) { backupSchedules_ = other.backupSchedules_; - bitField0_ |= 0x00002000; + bitField0_ |= 0x00008000; } else { ensureBackupSchedulesIsMutable(); backupSchedules_.addAll(other.backupSchedules_); } onChanged(); } + if (!other.getIncrementalBackupChainId().isEmpty()) { + incrementalBackupChainId_ = other.incrementalBackupChainId_; + bitField0_ |= 0x00010000; + onChanged(); + } + if (other.hasOldestVersionTime()) { + mergeOldestVersionTime(other.getOldestVersionTime()); + } this.mergeUnknownFields(other.getUnknownFields()); onChanged(); return this; @@ -1892,7 +2154,7 @@ public Builder mergeFrom( case 48: { state_ = input.readEnum(); - bitField0_ |= 0x00000040; + bitField0_ |= 0x00000100; break; } // case 48 case 58: @@ -1905,7 +2167,7 @@ public Builder mergeFrom( case 66: { input.readMessage(getEncryptionInfoFieldBuilder().getBuilder(), extensionRegistry); - bitField0_ |= 0x00000100; + bitField0_ |= 0x00000400; break; } // case 66 case 74: @@ -1917,7 +2179,7 @@ public Builder mergeFrom( case 80: { databaseDialect_ = input.readEnum(); - bitField0_ |= 0x00000400; + bitField0_ |= 0x00001000; break; } // case 80 case 90: @@ -1930,7 +2192,7 @@ public Builder mergeFrom( case 98: { input.readMessage(getMaxExpireTimeFieldBuilder().getBuilder(), extensionRegistry); - bitField0_ |= 0x00001000; + bitField0_ |= 0x00004000; break; } // case 98 case 106: @@ -1954,6 +2216,31 @@ public Builder mergeFrom( backupSchedules_.add(s); break; } // case 114 + case 120: + { + freeableSizeBytes_ = input.readInt64(); + bitField0_ |= 0x00000040; + break; + } // case 120 + case 128: + { + exclusiveSizeBytes_ = input.readInt64(); + bitField0_ |= 0x00000080; + break; + } // case 128 + case 138: + { + incrementalBackupChainId_ = input.readStringRequireUtf8(); + bitField0_ |= 0x00010000; + break; + } // case 138 + case 146: + { + input.readMessage( + getOldestVersionTimeFieldBuilder().getBuilder(), extensionRegistry); + bitField0_ |= 0x00020000; + break; + } // case 146 default: { if (!super.parseUnknownField(input, extensionRegistry, tag)) { @@ -3014,6 +3301,148 @@ public Builder clearSizeBytes() { return this; } + private long freeableSizeBytes_; + /** + * + * + *
+     * Output only. The number of bytes that will be freed by deleting this
+     * backup. This value will be zero if, for example, this backup is part of an
+     * incremental backup chain and younger backups in the chain require that we
+     * keep its data. For backups not in an incremental backup chain, this is
+     * always the size of the backup. This value may change if backups on the same
+     * chain get created, deleted or expired.
+     * 
+ * + * int64 freeable_size_bytes = 15 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + * @return The freeableSizeBytes. + */ + @java.lang.Override + public long getFreeableSizeBytes() { + return freeableSizeBytes_; + } + /** + * + * + *
+     * Output only. The number of bytes that will be freed by deleting this
+     * backup. This value will be zero if, for example, this backup is part of an
+     * incremental backup chain and younger backups in the chain require that we
+     * keep its data. For backups not in an incremental backup chain, this is
+     * always the size of the backup. This value may change if backups on the same
+     * chain get created, deleted or expired.
+     * 
+ * + * int64 freeable_size_bytes = 15 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + * @param value The freeableSizeBytes to set. + * @return This builder for chaining. + */ + public Builder setFreeableSizeBytes(long value) { + + freeableSizeBytes_ = value; + bitField0_ |= 0x00000040; + onChanged(); + return this; + } + /** + * + * + *
+     * Output only. The number of bytes that will be freed by deleting this
+     * backup. This value will be zero if, for example, this backup is part of an
+     * incremental backup chain and younger backups in the chain require that we
+     * keep its data. For backups not in an incremental backup chain, this is
+     * always the size of the backup. This value may change if backups on the same
+     * chain get created, deleted or expired.
+     * 
+ * + * int64 freeable_size_bytes = 15 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + * @return This builder for chaining. + */ + public Builder clearFreeableSizeBytes() { + bitField0_ = (bitField0_ & ~0x00000040); + freeableSizeBytes_ = 0L; + onChanged(); + return this; + } + + private long exclusiveSizeBytes_; + /** + * + * + *
+     * Output only. For a backup in an incremental backup chain, this is the
+     * storage space needed to keep the data that has changed since the previous
+     * backup. For all other backups, this is always the size of the backup. This
+     * value may change if backups on the same chain get deleted or expired.
+     *
+     * This field can be used to calculate the total storage space used by a set
+     * of backups. For example, the total space used by all backups of a database
+     * can be computed by summing up this field.
+     * 
+ * + * int64 exclusive_size_bytes = 16 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + * @return The exclusiveSizeBytes. + */ + @java.lang.Override + public long getExclusiveSizeBytes() { + return exclusiveSizeBytes_; + } + /** + * + * + *
+     * Output only. For a backup in an incremental backup chain, this is the
+     * storage space needed to keep the data that has changed since the previous
+     * backup. For all other backups, this is always the size of the backup. This
+     * value may change if backups on the same chain get deleted or expired.
+     *
+     * This field can be used to calculate the total storage space used by a set
+     * of backups. For example, the total space used by all backups of a database
+     * can be computed by summing up this field.
+     * 
+ * + * int64 exclusive_size_bytes = 16 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + * @param value The exclusiveSizeBytes to set. + * @return This builder for chaining. + */ + public Builder setExclusiveSizeBytes(long value) { + + exclusiveSizeBytes_ = value; + bitField0_ |= 0x00000080; + onChanged(); + return this; + } + /** + * + * + *
+     * Output only. For a backup in an incremental backup chain, this is the
+     * storage space needed to keep the data that has changed since the previous
+     * backup. For all other backups, this is always the size of the backup. This
+     * value may change if backups on the same chain get deleted or expired.
+     *
+     * This field can be used to calculate the total storage space used by a set
+     * of backups. For example, the total space used by all backups of a database
+     * can be computed by summing up this field.
+     * 
+ * + * int64 exclusive_size_bytes = 16 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + * @return This builder for chaining. + */ + public Builder clearExclusiveSizeBytes() { + bitField0_ = (bitField0_ & ~0x00000080); + exclusiveSizeBytes_ = 0L; + onChanged(); + return this; + } + private int state_ = 0; /** * @@ -3048,7 +3477,7 @@ public int getStateValue() { */ public Builder setStateValue(int value) { state_ = value; - bitField0_ |= 0x00000040; + bitField0_ |= 0x00000100; onChanged(); return this; } @@ -3091,7 +3520,7 @@ public Builder setState(com.google.spanner.admin.database.v1.Backup.State value) if (value == null) { throw new NullPointerException(); } - bitField0_ |= 0x00000040; + bitField0_ |= 0x00000100; state_ = value.getNumber(); onChanged(); return this; @@ -3110,7 +3539,7 @@ public Builder setState(com.google.spanner.admin.database.v1.Backup.State value) * @return This builder for chaining. */ public Builder clearState() { - bitField0_ = (bitField0_ & ~0x00000040); + bitField0_ = (bitField0_ & ~0x00000100); state_ = 0; onChanged(); return this; @@ -3123,7 +3552,7 @@ private void ensureReferencingDatabasesIsMutable() { if (!referencingDatabases_.isModifiable()) { referencingDatabases_ = new com.google.protobuf.LazyStringArrayList(referencingDatabases_); } - bitField0_ |= 0x00000080; + bitField0_ |= 0x00000200; } /** * @@ -3243,7 +3672,7 @@ public Builder setReferencingDatabases(int index, java.lang.String value) { } ensureReferencingDatabasesIsMutable(); referencingDatabases_.set(index, value); - bitField0_ |= 0x00000080; + bitField0_ |= 0x00000200; onChanged(); return this; } @@ -3273,7 +3702,7 @@ public Builder addReferencingDatabases(java.lang.String value) { } ensureReferencingDatabasesIsMutable(); referencingDatabases_.add(value); - bitField0_ |= 0x00000080; + bitField0_ |= 0x00000200; onChanged(); return this; } @@ -3300,7 +3729,7 @@ public Builder addReferencingDatabases(java.lang.String value) { public Builder addAllReferencingDatabases(java.lang.Iterable values) { ensureReferencingDatabasesIsMutable(); com.google.protobuf.AbstractMessageLite.Builder.addAll(values, referencingDatabases_); - bitField0_ |= 0x00000080; + bitField0_ |= 0x00000200; onChanged(); return this; } @@ -3325,7 +3754,7 @@ public Builder addAllReferencingDatabases(java.lang.Iterable v */ public Builder clearReferencingDatabases() { referencingDatabases_ = com.google.protobuf.LazyStringArrayList.emptyList(); - bitField0_ = (bitField0_ & ~0x00000080); + bitField0_ = (bitField0_ & ~0x00000200); ; onChanged(); return this; @@ -3357,7 +3786,7 @@ public Builder addReferencingDatabasesBytes(com.google.protobuf.ByteString value checkByteStringIsUtf8(value); ensureReferencingDatabasesIsMutable(); referencingDatabases_.add(value); - bitField0_ |= 0x00000080; + bitField0_ |= 0x00000200; onChanged(); return this; } @@ -3382,7 +3811,7 @@ public Builder addReferencingDatabasesBytes(com.google.protobuf.ByteString value * @return Whether the encryptionInfo field is set. */ public boolean hasEncryptionInfo() { - return ((bitField0_ & 0x00000100) != 0); + return ((bitField0_ & 0x00000400) != 0); } /** * @@ -3426,7 +3855,7 @@ public Builder setEncryptionInfo(com.google.spanner.admin.database.v1.Encryption } else { encryptionInfoBuilder_.setMessage(value); } - bitField0_ |= 0x00000100; + bitField0_ |= 0x00000400; onChanged(); return this; } @@ -3448,7 +3877,7 @@ public Builder setEncryptionInfo( } else { encryptionInfoBuilder_.setMessage(builderForValue.build()); } - bitField0_ |= 0x00000100; + bitField0_ |= 0x00000400; onChanged(); return this; } @@ -3465,7 +3894,7 @@ public Builder setEncryptionInfo( */ public Builder mergeEncryptionInfo(com.google.spanner.admin.database.v1.EncryptionInfo value) { if (encryptionInfoBuilder_ == null) { - if (((bitField0_ & 0x00000100) != 0) + if (((bitField0_ & 0x00000400) != 0) && encryptionInfo_ != null && encryptionInfo_ != com.google.spanner.admin.database.v1.EncryptionInfo.getDefaultInstance()) { @@ -3477,7 +3906,7 @@ public Builder mergeEncryptionInfo(com.google.spanner.admin.database.v1.Encrypti encryptionInfoBuilder_.mergeFrom(value); } if (encryptionInfo_ != null) { - bitField0_ |= 0x00000100; + bitField0_ |= 0x00000400; onChanged(); } return this; @@ -3494,7 +3923,7 @@ public Builder mergeEncryptionInfo(com.google.spanner.admin.database.v1.Encrypti *
*/ public Builder clearEncryptionInfo() { - bitField0_ = (bitField0_ & ~0x00000100); + bitField0_ = (bitField0_ & ~0x00000400); encryptionInfo_ = null; if (encryptionInfoBuilder_ != null) { encryptionInfoBuilder_.dispose(); @@ -3515,7 +3944,7 @@ public Builder clearEncryptionInfo() { *
*/ public com.google.spanner.admin.database.v1.EncryptionInfo.Builder getEncryptionInfoBuilder() { - bitField0_ |= 0x00000100; + bitField0_ |= 0x00000400; onChanged(); return getEncryptionInfoFieldBuilder().getBuilder(); } @@ -3572,11 +4001,11 @@ public com.google.spanner.admin.database.v1.EncryptionInfo.Builder getEncryption encryptionInformation_ = java.util.Collections.emptyList(); private void ensureEncryptionInformationIsMutable() { - if (!((bitField0_ & 0x00000200) != 0)) { + if (!((bitField0_ & 0x00000800) != 0)) { encryptionInformation_ = new java.util.ArrayList( encryptionInformation_); - bitField0_ |= 0x00000200; + bitField0_ |= 0x00000800; } } @@ -3873,7 +4302,7 @@ public Builder addAllEncryptionInformation( public Builder clearEncryptionInformation() { if (encryptionInformationBuilder_ == null) { encryptionInformation_ = java.util.Collections.emptyList(); - bitField0_ = (bitField0_ & ~0x00000200); + bitField0_ = (bitField0_ & ~0x00000800); onChanged(); } else { encryptionInformationBuilder_.clear(); @@ -4050,7 +4479,7 @@ public Builder removeEncryptionInformation(int index) { com.google.spanner.admin.database.v1.EncryptionInfo.Builder, com.google.spanner.admin.database.v1.EncryptionInfoOrBuilder>( encryptionInformation_, - ((bitField0_ & 0x00000200) != 0), + ((bitField0_ & 0x00000800) != 0), getParentForChildren(), isClean()); encryptionInformation_ = null; @@ -4092,7 +4521,7 @@ public int getDatabaseDialectValue() { */ public Builder setDatabaseDialectValue(int value) { databaseDialect_ = value; - bitField0_ |= 0x00000400; + bitField0_ |= 0x00001000; onChanged(); return this; } @@ -4135,7 +4564,7 @@ public Builder setDatabaseDialect(com.google.spanner.admin.database.v1.DatabaseD if (value == null) { throw new NullPointerException(); } - bitField0_ |= 0x00000400; + bitField0_ |= 0x00001000; databaseDialect_ = value.getNumber(); onChanged(); return this; @@ -4154,7 +4583,7 @@ public Builder setDatabaseDialect(com.google.spanner.admin.database.v1.DatabaseD * @return This builder for chaining. */ public Builder clearDatabaseDialect() { - bitField0_ = (bitField0_ & ~0x00000400); + bitField0_ = (bitField0_ & ~0x00001000); databaseDialect_ = 0; onChanged(); return this; @@ -4167,7 +4596,7 @@ private void ensureReferencingBackupsIsMutable() { if (!referencingBackups_.isModifiable()) { referencingBackups_ = new com.google.protobuf.LazyStringArrayList(referencingBackups_); } - bitField0_ |= 0x00000800; + bitField0_ |= 0x00002000; } /** * @@ -4287,7 +4716,7 @@ public Builder setReferencingBackups(int index, java.lang.String value) { } ensureReferencingBackupsIsMutable(); referencingBackups_.set(index, value); - bitField0_ |= 0x00000800; + bitField0_ |= 0x00002000; onChanged(); return this; } @@ -4317,7 +4746,7 @@ public Builder addReferencingBackups(java.lang.String value) { } ensureReferencingBackupsIsMutable(); referencingBackups_.add(value); - bitField0_ |= 0x00000800; + bitField0_ |= 0x00002000; onChanged(); return this; } @@ -4344,7 +4773,7 @@ public Builder addReferencingBackups(java.lang.String value) { public Builder addAllReferencingBackups(java.lang.Iterable values) { ensureReferencingBackupsIsMutable(); com.google.protobuf.AbstractMessageLite.Builder.addAll(values, referencingBackups_); - bitField0_ |= 0x00000800; + bitField0_ |= 0x00002000; onChanged(); return this; } @@ -4369,7 +4798,7 @@ public Builder addAllReferencingBackups(java.lang.Iterable val */ public Builder clearReferencingBackups() { referencingBackups_ = com.google.protobuf.LazyStringArrayList.emptyList(); - bitField0_ = (bitField0_ & ~0x00000800); + bitField0_ = (bitField0_ & ~0x00002000); ; onChanged(); return this; @@ -4401,7 +4830,7 @@ public Builder addReferencingBackupsBytes(com.google.protobuf.ByteString value) checkByteStringIsUtf8(value); ensureReferencingBackupsIsMutable(); referencingBackups_.add(value); - bitField0_ |= 0x00000800; + bitField0_ |= 0x00002000; onChanged(); return this; } @@ -4430,7 +4859,7 @@ public Builder addReferencingBackupsBytes(com.google.protobuf.ByteString value) * @return Whether the maxExpireTime field is set. */ public boolean hasMaxExpireTime() { - return ((bitField0_ & 0x00001000) != 0); + return ((bitField0_ & 0x00004000) != 0); } /** * @@ -4482,7 +4911,7 @@ public Builder setMaxExpireTime(com.google.protobuf.Timestamp value) { } else { maxExpireTimeBuilder_.setMessage(value); } - bitField0_ |= 0x00001000; + bitField0_ |= 0x00004000; onChanged(); return this; } @@ -4507,7 +4936,7 @@ public Builder setMaxExpireTime(com.google.protobuf.Timestamp.Builder builderFor } else { maxExpireTimeBuilder_.setMessage(builderForValue.build()); } - bitField0_ |= 0x00001000; + bitField0_ |= 0x00004000; onChanged(); return this; } @@ -4528,7 +4957,7 @@ public Builder setMaxExpireTime(com.google.protobuf.Timestamp.Builder builderFor */ public Builder mergeMaxExpireTime(com.google.protobuf.Timestamp value) { if (maxExpireTimeBuilder_ == null) { - if (((bitField0_ & 0x00001000) != 0) + if (((bitField0_ & 0x00004000) != 0) && maxExpireTime_ != null && maxExpireTime_ != com.google.protobuf.Timestamp.getDefaultInstance()) { getMaxExpireTimeBuilder().mergeFrom(value); @@ -4539,7 +4968,7 @@ public Builder mergeMaxExpireTime(com.google.protobuf.Timestamp value) { maxExpireTimeBuilder_.mergeFrom(value); } if (maxExpireTime_ != null) { - bitField0_ |= 0x00001000; + bitField0_ |= 0x00004000; onChanged(); } return this; @@ -4560,7 +4989,7 @@ public Builder mergeMaxExpireTime(com.google.protobuf.Timestamp value) { * */ public Builder clearMaxExpireTime() { - bitField0_ = (bitField0_ & ~0x00001000); + bitField0_ = (bitField0_ & ~0x00004000); maxExpireTime_ = null; if (maxExpireTimeBuilder_ != null) { maxExpireTimeBuilder_.dispose(); @@ -4585,7 +5014,7 @@ public Builder clearMaxExpireTime() { * */ public com.google.protobuf.Timestamp.Builder getMaxExpireTimeBuilder() { - bitField0_ |= 0x00001000; + bitField0_ |= 0x00004000; onChanged(); return getMaxExpireTimeFieldBuilder().getBuilder(); } @@ -4652,7 +5081,7 @@ private void ensureBackupSchedulesIsMutable() { if (!backupSchedules_.isModifiable()) { backupSchedules_ = new com.google.protobuf.LazyStringArrayList(backupSchedules_); } - bitField0_ |= 0x00002000; + bitField0_ |= 0x00008000; } /** * @@ -4777,7 +5206,7 @@ public Builder setBackupSchedules(int index, java.lang.String value) { } ensureBackupSchedulesIsMutable(); backupSchedules_.set(index, value); - bitField0_ |= 0x00002000; + bitField0_ |= 0x00008000; onChanged(); return this; } @@ -4808,7 +5237,7 @@ public Builder addBackupSchedules(java.lang.String value) { } ensureBackupSchedulesIsMutable(); backupSchedules_.add(value); - bitField0_ |= 0x00002000; + bitField0_ |= 0x00008000; onChanged(); return this; } @@ -4836,7 +5265,7 @@ public Builder addBackupSchedules(java.lang.String value) { public Builder addAllBackupSchedules(java.lang.Iterable values) { ensureBackupSchedulesIsMutable(); com.google.protobuf.AbstractMessageLite.Builder.addAll(values, backupSchedules_); - bitField0_ |= 0x00002000; + bitField0_ |= 0x00008000; onChanged(); return this; } @@ -4862,7 +5291,7 @@ public Builder addAllBackupSchedules(java.lang.Iterable values */ public Builder clearBackupSchedules() { backupSchedules_ = com.google.protobuf.LazyStringArrayList.emptyList(); - bitField0_ = (bitField0_ & ~0x00002000); + bitField0_ = (bitField0_ & ~0x00008000); ; onChanged(); return this; @@ -4895,10 +5324,389 @@ public Builder addBackupSchedulesBytes(com.google.protobuf.ByteString value) { checkByteStringIsUtf8(value); ensureBackupSchedulesIsMutable(); backupSchedules_.add(value); - bitField0_ |= 0x00002000; + bitField0_ |= 0x00008000; + onChanged(); + return this; + } + + private java.lang.Object incrementalBackupChainId_ = ""; + /** + * + * + *
+     * Output only. Populated only for backups in an incremental backup chain.
+     * Backups share the same chain id if and only if they belong to the same
+     * incremental backup chain. Use this field to determine which backups are
+     * part of the same incremental backup chain. The ordering of backups in the
+     * chain can be determined by ordering the backup `version_time`.
+     * 
+ * + * string incremental_backup_chain_id = 17 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + * + * @return The incrementalBackupChainId. + */ + public java.lang.String getIncrementalBackupChainId() { + java.lang.Object ref = incrementalBackupChainId_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + incrementalBackupChainId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * + * + *
+     * Output only. Populated only for backups in an incremental backup chain.
+     * Backups share the same chain id if and only if they belong to the same
+     * incremental backup chain. Use this field to determine which backups are
+     * part of the same incremental backup chain. The ordering of backups in the
+     * chain can be determined by ordering the backup `version_time`.
+     * 
+ * + * string incremental_backup_chain_id = 17 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + * + * @return The bytes for incrementalBackupChainId. + */ + public com.google.protobuf.ByteString getIncrementalBackupChainIdBytes() { + java.lang.Object ref = incrementalBackupChainId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8((java.lang.String) ref); + incrementalBackupChainId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * + * + *
+     * Output only. Populated only for backups in an incremental backup chain.
+     * Backups share the same chain id if and only if they belong to the same
+     * incremental backup chain. Use this field to determine which backups are
+     * part of the same incremental backup chain. The ordering of backups in the
+     * chain can be determined by ordering the backup `version_time`.
+     * 
+ * + * string incremental_backup_chain_id = 17 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + * + * @param value The incrementalBackupChainId to set. + * @return This builder for chaining. + */ + public Builder setIncrementalBackupChainId(java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + incrementalBackupChainId_ = value; + bitField0_ |= 0x00010000; + onChanged(); + return this; + } + /** + * + * + *
+     * Output only. Populated only for backups in an incremental backup chain.
+     * Backups share the same chain id if and only if they belong to the same
+     * incremental backup chain. Use this field to determine which backups are
+     * part of the same incremental backup chain. The ordering of backups in the
+     * chain can be determined by ordering the backup `version_time`.
+     * 
+ * + * string incremental_backup_chain_id = 17 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + * + * @return This builder for chaining. + */ + public Builder clearIncrementalBackupChainId() { + incrementalBackupChainId_ = getDefaultInstance().getIncrementalBackupChainId(); + bitField0_ = (bitField0_ & ~0x00010000); + onChanged(); + return this; + } + /** + * + * + *
+     * Output only. Populated only for backups in an incremental backup chain.
+     * Backups share the same chain id if and only if they belong to the same
+     * incremental backup chain. Use this field to determine which backups are
+     * part of the same incremental backup chain. The ordering of backups in the
+     * chain can be determined by ordering the backup `version_time`.
+     * 
+ * + * string incremental_backup_chain_id = 17 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + * + * @param value The bytes for incrementalBackupChainId to set. + * @return This builder for chaining. + */ + public Builder setIncrementalBackupChainIdBytes(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + incrementalBackupChainId_ = value; + bitField0_ |= 0x00010000; + onChanged(); + return this; + } + + private com.google.protobuf.Timestamp oldestVersionTime_; + private com.google.protobuf.SingleFieldBuilderV3< + com.google.protobuf.Timestamp, + com.google.protobuf.Timestamp.Builder, + com.google.protobuf.TimestampOrBuilder> + oldestVersionTimeBuilder_; + /** + * + * + *
+     * Output only. Data deleted at a time older than this is guaranteed not to be
+     * retained in order to support this backup. For a backup in an incremental
+     * backup chain, this is the version time of the oldest backup that exists or
+     * ever existed in the chain. For all other backups, this is the version time
+     * of the backup. This field can be used to understand what data is being
+     * retained by the backup system.
+     * 
+ * + * + * .google.protobuf.Timestamp oldest_version_time = 18 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + * + * @return Whether the oldestVersionTime field is set. + */ + public boolean hasOldestVersionTime() { + return ((bitField0_ & 0x00020000) != 0); + } + /** + * + * + *
+     * Output only. Data deleted at a time older than this is guaranteed not to be
+     * retained in order to support this backup. For a backup in an incremental
+     * backup chain, this is the version time of the oldest backup that exists or
+     * ever existed in the chain. For all other backups, this is the version time
+     * of the backup. This field can be used to understand what data is being
+     * retained by the backup system.
+     * 
+ * + * + * .google.protobuf.Timestamp oldest_version_time = 18 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + * + * @return The oldestVersionTime. + */ + public com.google.protobuf.Timestamp getOldestVersionTime() { + if (oldestVersionTimeBuilder_ == null) { + return oldestVersionTime_ == null + ? com.google.protobuf.Timestamp.getDefaultInstance() + : oldestVersionTime_; + } else { + return oldestVersionTimeBuilder_.getMessage(); + } + } + /** + * + * + *
+     * Output only. Data deleted at a time older than this is guaranteed not to be
+     * retained in order to support this backup. For a backup in an incremental
+     * backup chain, this is the version time of the oldest backup that exists or
+     * ever existed in the chain. For all other backups, this is the version time
+     * of the backup. This field can be used to understand what data is being
+     * retained by the backup system.
+     * 
+ * + * + * .google.protobuf.Timestamp oldest_version_time = 18 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + */ + public Builder setOldestVersionTime(com.google.protobuf.Timestamp value) { + if (oldestVersionTimeBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + oldestVersionTime_ = value; + } else { + oldestVersionTimeBuilder_.setMessage(value); + } + bitField0_ |= 0x00020000; + onChanged(); + return this; + } + /** + * + * + *
+     * Output only. Data deleted at a time older than this is guaranteed not to be
+     * retained in order to support this backup. For a backup in an incremental
+     * backup chain, this is the version time of the oldest backup that exists or
+     * ever existed in the chain. For all other backups, this is the version time
+     * of the backup. This field can be used to understand what data is being
+     * retained by the backup system.
+     * 
+ * + * + * .google.protobuf.Timestamp oldest_version_time = 18 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + */ + public Builder setOldestVersionTime(com.google.protobuf.Timestamp.Builder builderForValue) { + if (oldestVersionTimeBuilder_ == null) { + oldestVersionTime_ = builderForValue.build(); + } else { + oldestVersionTimeBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00020000; onChanged(); return this; } + /** + * + * + *
+     * Output only. Data deleted at a time older than this is guaranteed not to be
+     * retained in order to support this backup. For a backup in an incremental
+     * backup chain, this is the version time of the oldest backup that exists or
+     * ever existed in the chain. For all other backups, this is the version time
+     * of the backup. This field can be used to understand what data is being
+     * retained by the backup system.
+     * 
+ * + * + * .google.protobuf.Timestamp oldest_version_time = 18 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + */ + public Builder mergeOldestVersionTime(com.google.protobuf.Timestamp value) { + if (oldestVersionTimeBuilder_ == null) { + if (((bitField0_ & 0x00020000) != 0) + && oldestVersionTime_ != null + && oldestVersionTime_ != com.google.protobuf.Timestamp.getDefaultInstance()) { + getOldestVersionTimeBuilder().mergeFrom(value); + } else { + oldestVersionTime_ = value; + } + } else { + oldestVersionTimeBuilder_.mergeFrom(value); + } + if (oldestVersionTime_ != null) { + bitField0_ |= 0x00020000; + onChanged(); + } + return this; + } + /** + * + * + *
+     * Output only. Data deleted at a time older than this is guaranteed not to be
+     * retained in order to support this backup. For a backup in an incremental
+     * backup chain, this is the version time of the oldest backup that exists or
+     * ever existed in the chain. For all other backups, this is the version time
+     * of the backup. This field can be used to understand what data is being
+     * retained by the backup system.
+     * 
+ * + * + * .google.protobuf.Timestamp oldest_version_time = 18 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + */ + public Builder clearOldestVersionTime() { + bitField0_ = (bitField0_ & ~0x00020000); + oldestVersionTime_ = null; + if (oldestVersionTimeBuilder_ != null) { + oldestVersionTimeBuilder_.dispose(); + oldestVersionTimeBuilder_ = null; + } + onChanged(); + return this; + } + /** + * + * + *
+     * Output only. Data deleted at a time older than this is guaranteed not to be
+     * retained in order to support this backup. For a backup in an incremental
+     * backup chain, this is the version time of the oldest backup that exists or
+     * ever existed in the chain. For all other backups, this is the version time
+     * of the backup. This field can be used to understand what data is being
+     * retained by the backup system.
+     * 
+ * + * + * .google.protobuf.Timestamp oldest_version_time = 18 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + */ + public com.google.protobuf.Timestamp.Builder getOldestVersionTimeBuilder() { + bitField0_ |= 0x00020000; + onChanged(); + return getOldestVersionTimeFieldBuilder().getBuilder(); + } + /** + * + * + *
+     * Output only. Data deleted at a time older than this is guaranteed not to be
+     * retained in order to support this backup. For a backup in an incremental
+     * backup chain, this is the version time of the oldest backup that exists or
+     * ever existed in the chain. For all other backups, this is the version time
+     * of the backup. This field can be used to understand what data is being
+     * retained by the backup system.
+     * 
+ * + * + * .google.protobuf.Timestamp oldest_version_time = 18 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + */ + public com.google.protobuf.TimestampOrBuilder getOldestVersionTimeOrBuilder() { + if (oldestVersionTimeBuilder_ != null) { + return oldestVersionTimeBuilder_.getMessageOrBuilder(); + } else { + return oldestVersionTime_ == null + ? com.google.protobuf.Timestamp.getDefaultInstance() + : oldestVersionTime_; + } + } + /** + * + * + *
+     * Output only. Data deleted at a time older than this is guaranteed not to be
+     * retained in order to support this backup. For a backup in an incremental
+     * backup chain, this is the version time of the oldest backup that exists or
+     * ever existed in the chain. For all other backups, this is the version time
+     * of the backup. This field can be used to understand what data is being
+     * retained by the backup system.
+     * 
+ * + * + * .google.protobuf.Timestamp oldest_version_time = 18 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + */ + private com.google.protobuf.SingleFieldBuilderV3< + com.google.protobuf.Timestamp, + com.google.protobuf.Timestamp.Builder, + com.google.protobuf.TimestampOrBuilder> + getOldestVersionTimeFieldBuilder() { + if (oldestVersionTimeBuilder_ == null) { + oldestVersionTimeBuilder_ = + new com.google.protobuf.SingleFieldBuilderV3< + com.google.protobuf.Timestamp, + com.google.protobuf.Timestamp.Builder, + com.google.protobuf.TimestampOrBuilder>( + getOldestVersionTime(), getParentForChildren(), isClean()); + oldestVersionTime_ = null; + } + return oldestVersionTimeBuilder_; + } @java.lang.Override public final Builder setUnknownFields(final com.google.protobuf.UnknownFieldSet unknownFields) { diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupOrBuilder.java index ac1eec6a02..a89a0fdc2f 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupOrBuilder.java @@ -269,6 +269,44 @@ public interface BackupOrBuilder */ long getSizeBytes(); + /** + * + * + *
+   * Output only. The number of bytes that will be freed by deleting this
+   * backup. This value will be zero if, for example, this backup is part of an
+   * incremental backup chain and younger backups in the chain require that we
+   * keep its data. For backups not in an incremental backup chain, this is
+   * always the size of the backup. This value may change if backups on the same
+   * chain get created, deleted or expired.
+   * 
+ * + * int64 freeable_size_bytes = 15 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + * @return The freeableSizeBytes. + */ + long getFreeableSizeBytes(); + + /** + * + * + *
+   * Output only. For a backup in an incremental backup chain, this is the
+   * storage space needed to keep the data that has changed since the previous
+   * backup. For all other backups, this is always the size of the backup. This
+   * value may change if backups on the same chain get deleted or expired.
+   *
+   * This field can be used to calculate the total storage space used by a set
+   * of backups. For example, the total space used by all backups of a database
+   * can be computed by summing up this field.
+   * 
+ * + * int64 exclusive_size_bytes = 16 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + * @return The exclusiveSizeBytes. + */ + long getExclusiveSizeBytes(); + /** * * @@ -762,4 +800,95 @@ com.google.spanner.admin.database.v1.EncryptionInfoOrBuilder getEncryptionInform * @return The bytes of the backupSchedules at the given index. */ com.google.protobuf.ByteString getBackupSchedulesBytes(int index); + + /** + * + * + *
+   * Output only. Populated only for backups in an incremental backup chain.
+   * Backups share the same chain id if and only if they belong to the same
+   * incremental backup chain. Use this field to determine which backups are
+   * part of the same incremental backup chain. The ordering of backups in the
+   * chain can be determined by ordering the backup `version_time`.
+   * 
+ * + * string incremental_backup_chain_id = 17 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + * + * @return The incrementalBackupChainId. + */ + java.lang.String getIncrementalBackupChainId(); + /** + * + * + *
+   * Output only. Populated only for backups in an incremental backup chain.
+   * Backups share the same chain id if and only if they belong to the same
+   * incremental backup chain. Use this field to determine which backups are
+   * part of the same incremental backup chain. The ordering of backups in the
+   * chain can be determined by ordering the backup `version_time`.
+   * 
+ * + * string incremental_backup_chain_id = 17 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + * + * @return The bytes for incrementalBackupChainId. + */ + com.google.protobuf.ByteString getIncrementalBackupChainIdBytes(); + + /** + * + * + *
+   * Output only. Data deleted at a time older than this is guaranteed not to be
+   * retained in order to support this backup. For a backup in an incremental
+   * backup chain, this is the version time of the oldest backup that exists or
+   * ever existed in the chain. For all other backups, this is the version time
+   * of the backup. This field can be used to understand what data is being
+   * retained by the backup system.
+   * 
+ * + * + * .google.protobuf.Timestamp oldest_version_time = 18 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + * + * @return Whether the oldestVersionTime field is set. + */ + boolean hasOldestVersionTime(); + /** + * + * + *
+   * Output only. Data deleted at a time older than this is guaranteed not to be
+   * retained in order to support this backup. For a backup in an incremental
+   * backup chain, this is the version time of the oldest backup that exists or
+   * ever existed in the chain. For all other backups, this is the version time
+   * of the backup. This field can be used to understand what data is being
+   * retained by the backup system.
+   * 
+ * + * + * .google.protobuf.Timestamp oldest_version_time = 18 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + * + * @return The oldestVersionTime. + */ + com.google.protobuf.Timestamp getOldestVersionTime(); + /** + * + * + *
+   * Output only. Data deleted at a time older than this is guaranteed not to be
+   * retained in order to support this backup. For a backup in an incremental
+   * backup chain, this is the version time of the oldest backup that exists or
+   * ever existed in the chain. For all other backups, this is the version time
+   * of the backup. This field can be used to understand what data is being
+   * retained by the backup system.
+   * 
+ * + * + * .google.protobuf.Timestamp oldest_version_time = 18 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + */ + com.google.protobuf.TimestampOrBuilder getOldestVersionTimeOrBuilder(); } diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupProto.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupProto.java index 4f00e1d577..d2f0f5c38e 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupProto.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupProto.java @@ -92,6 +92,10 @@ public static void registerAllExtensions(com.google.protobuf.ExtensionRegistry r internal_static_google_spanner_admin_database_v1_FullBackupSpec_descriptor; static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internal_static_google_spanner_admin_database_v1_FullBackupSpec_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_google_spanner_admin_database_v1_IncrementalBackupSpec_descriptor; + static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_google_spanner_admin_database_v1_IncrementalBackupSpec_fieldAccessorTable; public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { return descriptor; @@ -108,111 +112,116 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { + "g/operations.proto\032 google/protobuf/fiel" + "d_mask.proto\032\037google/protobuf/timestamp." + "proto\032-google/spanner/admin/database/v1/" - + "common.proto\"\271\007\n\006Backup\0226\n\010database\030\002 \001(" + + "common.proto\"\346\010\n\006Backup\0226\n\010database\030\002 \001(" + "\tB$\372A!\n\037spanner.googleapis.com/Database\022" + "0\n\014version_time\030\t \001(\0132\032.google.protobuf." + "Timestamp\022/\n\013expire_time\030\003 \001(\0132\032.google." + "protobuf.Timestamp\022\014\n\004name\030\001 \001(\t\0224\n\013crea" + "te_time\030\004 \001(\0132\032.google.protobuf.Timestam" - + "pB\003\340A\003\022\027\n\nsize_bytes\030\005 \001(\003B\003\340A\003\022B\n\005state" - + "\030\006 \001(\0162..google.spanner.admin.database.v" - + "1.Backup.StateB\003\340A\003\022F\n\025referencing_datab" - + "ases\030\007 \003(\tB\'\340A\003\372A!\n\037spanner.googleapis.c" - + "om/Database\022N\n\017encryption_info\030\010 \001(\01320.g" - + "oogle.spanner.admin.database.v1.Encrypti" - + "onInfoB\003\340A\003\022U\n\026encryption_information\030\r " - + "\003(\01320.google.spanner.admin.database.v1.E" - + "ncryptionInfoB\003\340A\003\022P\n\020database_dialect\030\n" - + " \001(\01621.google.spanner.admin.database.v1." - + "DatabaseDialectB\003\340A\003\022B\n\023referencing_back" - + "ups\030\013 \003(\tB%\340A\003\372A\037\n\035spanner.googleapis.co" - + "m/Backup\0228\n\017max_expire_time\030\014 \001(\0132\032.goog" - + "le.protobuf.TimestampB\003\340A\003\022\035\n\020backup_sch" - + "edules\030\016 \003(\tB\003\340A\003\"7\n\005State\022\025\n\021STATE_UNSP" - + "ECIFIED\020\000\022\014\n\010CREATING\020\001\022\t\n\005READY\020\002:\\\352AY\n" - + "\035spanner.googleapis.com/Backup\0228projects" - + "/{project}/instances/{instance}/backups/" - + "{backup}\"\205\002\n\023CreateBackupRequest\0227\n\006pare" - + "nt\030\001 \001(\tB\'\340A\002\372A!\n\037spanner.googleapis.com" - + "/Instance\022\026\n\tbackup_id\030\002 \001(\tB\003\340A\002\022=\n\006bac" - + "kup\030\003 \001(\0132(.google.spanner.admin.databas" - + "e.v1.BackupB\003\340A\002\022^\n\021encryption_config\030\004 " - + "\001(\0132>.google.spanner.admin.database.v1.C" - + "reateBackupEncryptionConfigB\003\340A\001\"\370\001\n\024Cre" - + "ateBackupMetadata\0220\n\004name\030\001 \001(\tB\"\372A\037\n\035sp" - + "anner.googleapis.com/Backup\0226\n\010database\030" - + "\002 \001(\tB$\372A!\n\037spanner.googleapis.com/Datab" - + "ase\022E\n\010progress\030\003 \001(\01323.google.spanner.a" - + "dmin.database.v1.OperationProgress\022/\n\013ca" - + "ncel_time\030\004 \001(\0132\032.google.protobuf.Timest" - + "amp\"\266\002\n\021CopyBackupRequest\0227\n\006parent\030\001 \001(" + + "pB\003\340A\003\022\027\n\nsize_bytes\030\005 \001(\003B\003\340A\003\022 \n\023freea" + + "ble_size_bytes\030\017 \001(\003B\003\340A\003\022!\n\024exclusive_s" + + "ize_bytes\030\020 \001(\003B\003\340A\003\022B\n\005state\030\006 \001(\0162..go" + + "ogle.spanner.admin.database.v1.Backup.St" + + "ateB\003\340A\003\022F\n\025referencing_databases\030\007 \003(\tB" + + "\'\340A\003\372A!\n\037spanner.googleapis.com/Database" + + "\022N\n\017encryption_info\030\010 \001(\01320.google.spann" + + "er.admin.database.v1.EncryptionInfoB\003\340A\003" + + "\022U\n\026encryption_information\030\r \003(\01320.googl" + + "e.spanner.admin.database.v1.EncryptionIn" + + "foB\003\340A\003\022P\n\020database_dialect\030\n \001(\01621.goog" + + "le.spanner.admin.database.v1.DatabaseDia" + + "lectB\003\340A\003\022B\n\023referencing_backups\030\013 \003(\tB%" + + "\340A\003\372A\037\n\035spanner.googleapis.com/Backup\0228\n" + + "\017max_expire_time\030\014 \001(\0132\032.google.protobuf" + + ".TimestampB\003\340A\003\022\035\n\020backup_schedules\030\016 \003(" + + "\tB\003\340A\003\022(\n\033incremental_backup_chain_id\030\021 " + + "\001(\tB\003\340A\003\022<\n\023oldest_version_time\030\022 \001(\0132\032." + + "google.protobuf.TimestampB\003\340A\003\"7\n\005State\022" + + "\025\n\021STATE_UNSPECIFIED\020\000\022\014\n\010CREATING\020\001\022\t\n\005" + + "READY\020\002:\\\352AY\n\035spanner.googleapis.com/Bac" + + "kup\0228projects/{project}/instances/{insta" + + "nce}/backups/{backup}\"\205\002\n\023CreateBackupRe" + + "quest\0227\n\006parent\030\001 \001(\tB\'\340A\002\372A!\n\037spanner.g" + + "oogleapis.com/Instance\022\026\n\tbackup_id\030\002 \001(" + + "\tB\003\340A\002\022=\n\006backup\030\003 \001(\0132(.google.spanner." + + "admin.database.v1.BackupB\003\340A\002\022^\n\021encrypt" + + "ion_config\030\004 \001(\0132>.google.spanner.admin." + + "database.v1.CreateBackupEncryptionConfig" + + "B\003\340A\001\"\370\001\n\024CreateBackupMetadata\0220\n\004name\030\001" + + " \001(\tB\"\372A\037\n\035spanner.googleapis.com/Backup" + + "\0226\n\010database\030\002 \001(\tB$\372A!\n\037spanner.googlea" + + "pis.com/Database\022E\n\010progress\030\003 \001(\01323.goo" + + "gle.spanner.admin.database.v1.OperationP" + + "rogress\022/\n\013cancel_time\030\004 \001(\0132\032.google.pr" + + "otobuf.Timestamp\"\266\002\n\021CopyBackupRequest\0227" + + "\n\006parent\030\001 \001(\tB\'\340A\002\372A!\n\037spanner.googleap" + + "is.com/Instance\022\026\n\tbackup_id\030\002 \001(\tB\003\340A\002\022" + + "<\n\rsource_backup\030\003 \001(\tB%\340A\002\372A\037\n\035spanner." + + "googleapis.com/Backup\0224\n\013expire_time\030\004 \001" + + "(\0132\032.google.protobuf.TimestampB\003\340A\002\022\\\n\021e" + + "ncryption_config\030\005 \001(\0132<.google.spanner." + + "admin.database.v1.CopyBackupEncryptionCo" + + "nfigB\003\340A\001\"\371\001\n\022CopyBackupMetadata\0220\n\004name" + + "\030\001 \001(\tB\"\372A\037\n\035spanner.googleapis.com/Back" + + "up\0229\n\rsource_backup\030\002 \001(\tB\"\372A\037\n\035spanner." + + "googleapis.com/Backup\022E\n\010progress\030\003 \001(\0132" + + "3.google.spanner.admin.database.v1.Opera" + + "tionProgress\022/\n\013cancel_time\030\004 \001(\0132\032.goog" + + "le.protobuf.Timestamp\"\212\001\n\023UpdateBackupRe" + + "quest\022=\n\006backup\030\001 \001(\0132(.google.spanner.a" + + "dmin.database.v1.BackupB\003\340A\002\0224\n\013update_m" + + "ask\030\002 \001(\0132\032.google.protobuf.FieldMaskB\003\340" + + "A\002\"G\n\020GetBackupRequest\0223\n\004name\030\001 \001(\tB%\340A" + + "\002\372A\037\n\035spanner.googleapis.com/Backup\"J\n\023D" + + "eleteBackupRequest\0223\n\004name\030\001 \001(\tB%\340A\002\372A\037" + + "\n\035spanner.googleapis.com/Backup\"\204\001\n\022List" + + "BackupsRequest\0227\n\006parent\030\001 \001(\tB\'\340A\002\372A!\n\037" + + "spanner.googleapis.com/Instance\022\016\n\006filte" + + "r\030\002 \001(\t\022\021\n\tpage_size\030\003 \001(\005\022\022\n\npage_token" + + "\030\004 \001(\t\"i\n\023ListBackupsResponse\0229\n\007backups" + + "\030\001 \003(\0132(.google.spanner.admin.database.v" + + "1.Backup\022\027\n\017next_page_token\030\002 \001(\t\"\215\001\n\033Li" + + "stBackupOperationsRequest\0227\n\006parent\030\001 \001(" + "\tB\'\340A\002\372A!\n\037spanner.googleapis.com/Instan" - + "ce\022\026\n\tbackup_id\030\002 \001(\tB\003\340A\002\022<\n\rsource_bac" - + "kup\030\003 \001(\tB%\340A\002\372A\037\n\035spanner.googleapis.co" - + "m/Backup\0224\n\013expire_time\030\004 \001(\0132\032.google.p" - + "rotobuf.TimestampB\003\340A\002\022\\\n\021encryption_con" - + "fig\030\005 \001(\0132<.google.spanner.admin.databas" - + "e.v1.CopyBackupEncryptionConfigB\003\340A\001\"\371\001\n" - + "\022CopyBackupMetadata\0220\n\004name\030\001 \001(\tB\"\372A\037\n\035" - + "spanner.googleapis.com/Backup\0229\n\rsource_" - + "backup\030\002 \001(\tB\"\372A\037\n\035spanner.googleapis.co" - + "m/Backup\022E\n\010progress\030\003 \001(\01323.google.span" - + "ner.admin.database.v1.OperationProgress\022" - + "/\n\013cancel_time\030\004 \001(\0132\032.google.protobuf.T" - + "imestamp\"\212\001\n\023UpdateBackupRequest\022=\n\006back" - + "up\030\001 \001(\0132(.google.spanner.admin.database" - + ".v1.BackupB\003\340A\002\0224\n\013update_mask\030\002 \001(\0132\032.g" - + "oogle.protobuf.FieldMaskB\003\340A\002\"G\n\020GetBack" - + "upRequest\0223\n\004name\030\001 \001(\tB%\340A\002\372A\037\n\035spanner" - + ".googleapis.com/Backup\"J\n\023DeleteBackupRe" - + "quest\0223\n\004name\030\001 \001(\tB%\340A\002\372A\037\n\035spanner.goo" - + "gleapis.com/Backup\"\204\001\n\022ListBackupsReques" - + "t\0227\n\006parent\030\001 \001(\tB\'\340A\002\372A!\n\037spanner.googl" - + "eapis.com/Instance\022\016\n\006filter\030\002 \001(\t\022\021\n\tpa" - + "ge_size\030\003 \001(\005\022\022\n\npage_token\030\004 \001(\t\"i\n\023Lis" - + "tBackupsResponse\0229\n\007backups\030\001 \003(\0132(.goog" - + "le.spanner.admin.database.v1.Backup\022\027\n\017n" - + "ext_page_token\030\002 \001(\t\"\215\001\n\033ListBackupOpera" - + "tionsRequest\0227\n\006parent\030\001 \001(\tB\'\340A\002\372A!\n\037sp" - + "anner.googleapis.com/Instance\022\016\n\006filter\030" - + "\002 \001(\t\022\021\n\tpage_size\030\003 \001(\005\022\022\n\npage_token\030\004" - + " \001(\t\"j\n\034ListBackupOperationsResponse\0221\n\n" - + "operations\030\001 \003(\0132\035.google.longrunning.Op" - + "eration\022\027\n\017next_page_token\030\002 \001(\t\"\342\001\n\nBac" - + "kupInfo\0222\n\006backup\030\001 \001(\tB\"\372A\037\n\035spanner.go" - + "ogleapis.com/Backup\0220\n\014version_time\030\004 \001(" - + "\0132\032.google.protobuf.Timestamp\022/\n\013create_" - + "time\030\002 \001(\0132\032.google.protobuf.Timestamp\022=" - + "\n\017source_database\030\003 \001(\tB$\372A!\n\037spanner.go" - + "ogleapis.com/Database\"\237\003\n\034CreateBackupEn" - + "cryptionConfig\022k\n\017encryption_type\030\001 \001(\0162" - + "M.google.spanner.admin.database.v1.Creat" - + "eBackupEncryptionConfig.EncryptionTypeB\003" - + "\340A\002\022?\n\014kms_key_name\030\002 \001(\tB)\340A\001\372A#\n!cloud" - + "kms.googleapis.com/CryptoKey\022@\n\rkms_key_" - + "names\030\003 \003(\tB)\340A\001\372A#\n!cloudkms.googleapis" - + ".com/CryptoKey\"\216\001\n\016EncryptionType\022\037\n\033ENC" - + "RYPTION_TYPE_UNSPECIFIED\020\000\022\033\n\027USE_DATABA" - + "SE_ENCRYPTION\020\001\022\035\n\031GOOGLE_DEFAULT_ENCRYP" - + "TION\020\002\022\037\n\033CUSTOMER_MANAGED_ENCRYPTION\020\003\"" - + "\253\003\n\032CopyBackupEncryptionConfig\022i\n\017encryp" - + "tion_type\030\001 \001(\0162K.google.spanner.admin.d" - + "atabase.v1.CopyBackupEncryptionConfig.En" - + "cryptionTypeB\003\340A\002\022?\n\014kms_key_name\030\002 \001(\tB" - + ")\340A\001\372A#\n!cloudkms.googleapis.com/CryptoK" - + "ey\022@\n\rkms_key_names\030\003 \003(\tB)\340A\001\372A#\n!cloud" - + "kms.googleapis.com/CryptoKey\"\236\001\n\016Encrypt" - + "ionType\022\037\n\033ENCRYPTION_TYPE_UNSPECIFIED\020\000" - + "\022+\n\'USE_CONFIG_DEFAULT_OR_BACKUP_ENCRYPT" - + "ION\020\001\022\035\n\031GOOGLE_DEFAULT_ENCRYPTION\020\002\022\037\n\033" - + "CUSTOMER_MANAGED_ENCRYPTION\020\003\"\020\n\016FullBac" - + "kupSpecB\375\001\n$com.google.spanner.admin.dat" - + "abase.v1B\013BackupProtoP\001ZFcloud.google.co" - + "m/go/spanner/admin/database/apiv1/databa" - + "sepb;databasepb\252\002&Google.Cloud.Spanner.A" - + "dmin.Database.V1\312\002&Google\\Cloud\\Spanner\\" - + "Admin\\Database\\V1\352\002+Google::Cloud::Spann" - + "er::Admin::Database::V1b\006proto3" + + "ce\022\016\n\006filter\030\002 \001(\t\022\021\n\tpage_size\030\003 \001(\005\022\022\n" + + "\npage_token\030\004 \001(\t\"j\n\034ListBackupOperation" + + "sResponse\0221\n\noperations\030\001 \003(\0132\035.google.l" + + "ongrunning.Operation\022\027\n\017next_page_token\030" + + "\002 \001(\t\"\342\001\n\nBackupInfo\0222\n\006backup\030\001 \001(\tB\"\372A" + + "\037\n\035spanner.googleapis.com/Backup\0220\n\014vers" + + "ion_time\030\004 \001(\0132\032.google.protobuf.Timesta" + + "mp\022/\n\013create_time\030\002 \001(\0132\032.google.protobu" + + "f.Timestamp\022=\n\017source_database\030\003 \001(\tB$\372A" + + "!\n\037spanner.googleapis.com/Database\"\237\003\n\034C" + + "reateBackupEncryptionConfig\022k\n\017encryptio" + + "n_type\030\001 \001(\0162M.google.spanner.admin.data" + + "base.v1.CreateBackupEncryptionConfig.Enc" + + "ryptionTypeB\003\340A\002\022?\n\014kms_key_name\030\002 \001(\tB)" + + "\340A\001\372A#\n!cloudkms.googleapis.com/CryptoKe" + + "y\022@\n\rkms_key_names\030\003 \003(\tB)\340A\001\372A#\n!cloudk" + + "ms.googleapis.com/CryptoKey\"\216\001\n\016Encrypti" + + "onType\022\037\n\033ENCRYPTION_TYPE_UNSPECIFIED\020\000\022" + + "\033\n\027USE_DATABASE_ENCRYPTION\020\001\022\035\n\031GOOGLE_D" + + "EFAULT_ENCRYPTION\020\002\022\037\n\033CUSTOMER_MANAGED_" + + "ENCRYPTION\020\003\"\253\003\n\032CopyBackupEncryptionCon" + + "fig\022i\n\017encryption_type\030\001 \001(\0162K.google.sp" + + "anner.admin.database.v1.CopyBackupEncryp" + + "tionConfig.EncryptionTypeB\003\340A\002\022?\n\014kms_ke" + + "y_name\030\002 \001(\tB)\340A\001\372A#\n!cloudkms.googleapi" + + "s.com/CryptoKey\022@\n\rkms_key_names\030\003 \003(\tB)" + + "\340A\001\372A#\n!cloudkms.googleapis.com/CryptoKe" + + "y\"\236\001\n\016EncryptionType\022\037\n\033ENCRYPTION_TYPE_" + + "UNSPECIFIED\020\000\022+\n\'USE_CONFIG_DEFAULT_OR_B" + + "ACKUP_ENCRYPTION\020\001\022\035\n\031GOOGLE_DEFAULT_ENC" + + "RYPTION\020\002\022\037\n\033CUSTOMER_MANAGED_ENCRYPTION" + + "\020\003\"\020\n\016FullBackupSpec\"\027\n\025IncrementalBacku" + + "pSpecB\375\001\n$com.google.spanner.admin.datab" + + "ase.v1B\013BackupProtoP\001ZFcloud.google.com/" + + "go/spanner/admin/database/apiv1/database" + + "pb;databasepb\252\002&Google.Cloud.Spanner.Adm" + + "in.Database.V1\312\002&Google\\Cloud\\Spanner\\Ad" + + "min\\Database\\V1\352\002+Google::Cloud::Spanner" + + "::Admin::Database::V1b\006proto3" }; descriptor = com.google.protobuf.Descriptors.FileDescriptor.internalBuildGeneratedFileFrom( @@ -237,6 +246,8 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { "Name", "CreateTime", "SizeBytes", + "FreeableSizeBytes", + "ExclusiveSizeBytes", "State", "ReferencingDatabases", "EncryptionInfo", @@ -245,6 +256,8 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { "ReferencingBackups", "MaxExpireTime", "BackupSchedules", + "IncrementalBackupChainId", + "OldestVersionTime", }); internal_static_google_spanner_admin_database_v1_CreateBackupRequest_descriptor = getDescriptor().getMessageTypes().get(1); @@ -364,6 +377,12 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_google_spanner_admin_database_v1_FullBackupSpec_descriptor, new java.lang.String[] {}); + internal_static_google_spanner_admin_database_v1_IncrementalBackupSpec_descriptor = + getDescriptor().getMessageTypes().get(16); + internal_static_google_spanner_admin_database_v1_IncrementalBackupSpec_fieldAccessorTable = + new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_google_spanner_admin_database_v1_IncrementalBackupSpec_descriptor, + new java.lang.String[] {}); com.google.protobuf.ExtensionRegistry registry = com.google.protobuf.ExtensionRegistry.newInstance(); registry.add(com.google.api.FieldBehaviorProto.fieldBehavior); diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupSchedule.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupSchedule.java index eb5fc00ab9..c4f5495651 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupSchedule.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupSchedule.java @@ -76,6 +76,7 @@ public enum BackupTypeSpecCase com.google.protobuf.Internal.EnumLite, com.google.protobuf.AbstractMessage.InternalOneOfEnum { FULL_BACKUP_SPEC(7), + INCREMENTAL_BACKUP_SPEC(8), BACKUPTYPESPEC_NOT_SET(0); private final int value; @@ -96,6 +97,8 @@ public static BackupTypeSpecCase forNumber(int value) { switch (value) { case 7: return FULL_BACKUP_SPEC; + case 8: + return INCREMENTAL_BACKUP_SPEC; case 0: return BACKUPTYPESPEC_NOT_SET; default: @@ -414,6 +417,61 @@ public com.google.spanner.admin.database.v1.FullBackupSpecOrBuilder getFullBacku return com.google.spanner.admin.database.v1.FullBackupSpec.getDefaultInstance(); } + public static final int INCREMENTAL_BACKUP_SPEC_FIELD_NUMBER = 8; + /** + * + * + *
+   * The schedule creates incremental backup chains.
+   * 
+ * + * .google.spanner.admin.database.v1.IncrementalBackupSpec incremental_backup_spec = 8; + * + * + * @return Whether the incrementalBackupSpec field is set. + */ + @java.lang.Override + public boolean hasIncrementalBackupSpec() { + return backupTypeSpecCase_ == 8; + } + /** + * + * + *
+   * The schedule creates incremental backup chains.
+   * 
+ * + * .google.spanner.admin.database.v1.IncrementalBackupSpec incremental_backup_spec = 8; + * + * + * @return The incrementalBackupSpec. + */ + @java.lang.Override + public com.google.spanner.admin.database.v1.IncrementalBackupSpec getIncrementalBackupSpec() { + if (backupTypeSpecCase_ == 8) { + return (com.google.spanner.admin.database.v1.IncrementalBackupSpec) backupTypeSpec_; + } + return com.google.spanner.admin.database.v1.IncrementalBackupSpec.getDefaultInstance(); + } + /** + * + * + *
+   * The schedule creates incremental backup chains.
+   * 
+ * + * .google.spanner.admin.database.v1.IncrementalBackupSpec incremental_backup_spec = 8; + * + */ + @java.lang.Override + public com.google.spanner.admin.database.v1.IncrementalBackupSpecOrBuilder + getIncrementalBackupSpecOrBuilder() { + if (backupTypeSpecCase_ == 8) { + return (com.google.spanner.admin.database.v1.IncrementalBackupSpec) backupTypeSpec_; + } + return com.google.spanner.admin.database.v1.IncrementalBackupSpec.getDefaultInstance(); + } + public static final int UPDATE_TIME_FIELD_NUMBER = 9; private com.google.protobuf.Timestamp updateTime_; /** @@ -498,6 +556,10 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io if (backupTypeSpecCase_ == 7) { output.writeMessage(7, (com.google.spanner.admin.database.v1.FullBackupSpec) backupTypeSpec_); } + if (backupTypeSpecCase_ == 8) { + output.writeMessage( + 8, (com.google.spanner.admin.database.v1.IncrementalBackupSpec) backupTypeSpec_); + } if (((bitField0_ & 0x00000008) != 0)) { output.writeMessage(9, getUpdateTime()); } @@ -527,6 +589,11 @@ public int getSerializedSize() { com.google.protobuf.CodedOutputStream.computeMessageSize( 7, (com.google.spanner.admin.database.v1.FullBackupSpec) backupTypeSpec_); } + if (backupTypeSpecCase_ == 8) { + size += + com.google.protobuf.CodedOutputStream.computeMessageSize( + 8, (com.google.spanner.admin.database.v1.IncrementalBackupSpec) backupTypeSpec_); + } if (((bitField0_ & 0x00000008) != 0)) { size += com.google.protobuf.CodedOutputStream.computeMessageSize(9, getUpdateTime()); } @@ -568,6 +635,9 @@ public boolean equals(final java.lang.Object obj) { case 7: if (!getFullBackupSpec().equals(other.getFullBackupSpec())) return false; break; + case 8: + if (!getIncrementalBackupSpec().equals(other.getIncrementalBackupSpec())) return false; + break; case 0: default: } @@ -605,6 +675,10 @@ public int hashCode() { hash = (37 * hash) + FULL_BACKUP_SPEC_FIELD_NUMBER; hash = (53 * hash) + getFullBackupSpec().hashCode(); break; + case 8: + hash = (37 * hash) + INCREMENTAL_BACKUP_SPEC_FIELD_NUMBER; + hash = (53 * hash) + getIncrementalBackupSpec().hashCode(); + break; case 0: default: } @@ -780,6 +854,9 @@ public Builder clear() { if (fullBackupSpecBuilder_ != null) { fullBackupSpecBuilder_.clear(); } + if (incrementalBackupSpecBuilder_ != null) { + incrementalBackupSpecBuilder_.clear(); + } updateTime_ = null; if (updateTimeBuilder_ != null) { updateTimeBuilder_.dispose(); @@ -844,7 +921,7 @@ private void buildPartial0(com.google.spanner.admin.database.v1.BackupSchedule r encryptionConfigBuilder_ == null ? encryptionConfig_ : encryptionConfigBuilder_.build(); to_bitField0_ |= 0x00000004; } - if (((from_bitField0_ & 0x00000020) != 0)) { + if (((from_bitField0_ & 0x00000040) != 0)) { result.updateTime_ = updateTimeBuilder_ == null ? updateTime_ : updateTimeBuilder_.build(); to_bitField0_ |= 0x00000008; } @@ -857,6 +934,9 @@ private void buildPartialOneofs(com.google.spanner.admin.database.v1.BackupSched if (backupTypeSpecCase_ == 7 && fullBackupSpecBuilder_ != null) { result.backupTypeSpec_ = fullBackupSpecBuilder_.build(); } + if (backupTypeSpecCase_ == 8 && incrementalBackupSpecBuilder_ != null) { + result.backupTypeSpec_ = incrementalBackupSpecBuilder_.build(); + } } @java.lang.Override @@ -928,6 +1008,11 @@ public Builder mergeFrom(com.google.spanner.admin.database.v1.BackupSchedule oth mergeFullBackupSpec(other.getFullBackupSpec()); break; } + case INCREMENTAL_BACKUP_SPEC: + { + mergeIncrementalBackupSpec(other.getIncrementalBackupSpec()); + break; + } case BACKUPTYPESPEC_NOT_SET: { break; @@ -991,10 +1076,17 @@ public Builder mergeFrom( backupTypeSpecCase_ = 7; break; } // case 58 + case 66: + { + input.readMessage( + getIncrementalBackupSpecFieldBuilder().getBuilder(), extensionRegistry); + backupTypeSpecCase_ = 8; + break; + } // case 66 case 74: { input.readMessage(getUpdateTimeFieldBuilder().getBuilder(), extensionRegistry); - bitField0_ |= 0x00000020; + bitField0_ |= 0x00000040; break; } // case 74 default: @@ -2051,6 +2143,231 @@ public com.google.spanner.admin.database.v1.FullBackupSpec.Builder getFullBackup return fullBackupSpecBuilder_; } + private com.google.protobuf.SingleFieldBuilderV3< + com.google.spanner.admin.database.v1.IncrementalBackupSpec, + com.google.spanner.admin.database.v1.IncrementalBackupSpec.Builder, + com.google.spanner.admin.database.v1.IncrementalBackupSpecOrBuilder> + incrementalBackupSpecBuilder_; + /** + * + * + *
+     * The schedule creates incremental backup chains.
+     * 
+ * + * .google.spanner.admin.database.v1.IncrementalBackupSpec incremental_backup_spec = 8; + * + * + * @return Whether the incrementalBackupSpec field is set. + */ + @java.lang.Override + public boolean hasIncrementalBackupSpec() { + return backupTypeSpecCase_ == 8; + } + /** + * + * + *
+     * The schedule creates incremental backup chains.
+     * 
+ * + * .google.spanner.admin.database.v1.IncrementalBackupSpec incremental_backup_spec = 8; + * + * + * @return The incrementalBackupSpec. + */ + @java.lang.Override + public com.google.spanner.admin.database.v1.IncrementalBackupSpec getIncrementalBackupSpec() { + if (incrementalBackupSpecBuilder_ == null) { + if (backupTypeSpecCase_ == 8) { + return (com.google.spanner.admin.database.v1.IncrementalBackupSpec) backupTypeSpec_; + } + return com.google.spanner.admin.database.v1.IncrementalBackupSpec.getDefaultInstance(); + } else { + if (backupTypeSpecCase_ == 8) { + return incrementalBackupSpecBuilder_.getMessage(); + } + return com.google.spanner.admin.database.v1.IncrementalBackupSpec.getDefaultInstance(); + } + } + /** + * + * + *
+     * The schedule creates incremental backup chains.
+     * 
+ * + * .google.spanner.admin.database.v1.IncrementalBackupSpec incremental_backup_spec = 8; + * + */ + public Builder setIncrementalBackupSpec( + com.google.spanner.admin.database.v1.IncrementalBackupSpec value) { + if (incrementalBackupSpecBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + backupTypeSpec_ = value; + onChanged(); + } else { + incrementalBackupSpecBuilder_.setMessage(value); + } + backupTypeSpecCase_ = 8; + return this; + } + /** + * + * + *
+     * The schedule creates incremental backup chains.
+     * 
+ * + * .google.spanner.admin.database.v1.IncrementalBackupSpec incremental_backup_spec = 8; + * + */ + public Builder setIncrementalBackupSpec( + com.google.spanner.admin.database.v1.IncrementalBackupSpec.Builder builderForValue) { + if (incrementalBackupSpecBuilder_ == null) { + backupTypeSpec_ = builderForValue.build(); + onChanged(); + } else { + incrementalBackupSpecBuilder_.setMessage(builderForValue.build()); + } + backupTypeSpecCase_ = 8; + return this; + } + /** + * + * + *
+     * The schedule creates incremental backup chains.
+     * 
+ * + * .google.spanner.admin.database.v1.IncrementalBackupSpec incremental_backup_spec = 8; + * + */ + public Builder mergeIncrementalBackupSpec( + com.google.spanner.admin.database.v1.IncrementalBackupSpec value) { + if (incrementalBackupSpecBuilder_ == null) { + if (backupTypeSpecCase_ == 8 + && backupTypeSpec_ + != com.google.spanner.admin.database.v1.IncrementalBackupSpec + .getDefaultInstance()) { + backupTypeSpec_ = + com.google.spanner.admin.database.v1.IncrementalBackupSpec.newBuilder( + (com.google.spanner.admin.database.v1.IncrementalBackupSpec) backupTypeSpec_) + .mergeFrom(value) + .buildPartial(); + } else { + backupTypeSpec_ = value; + } + onChanged(); + } else { + if (backupTypeSpecCase_ == 8) { + incrementalBackupSpecBuilder_.mergeFrom(value); + } else { + incrementalBackupSpecBuilder_.setMessage(value); + } + } + backupTypeSpecCase_ = 8; + return this; + } + /** + * + * + *
+     * The schedule creates incremental backup chains.
+     * 
+ * + * .google.spanner.admin.database.v1.IncrementalBackupSpec incremental_backup_spec = 8; + * + */ + public Builder clearIncrementalBackupSpec() { + if (incrementalBackupSpecBuilder_ == null) { + if (backupTypeSpecCase_ == 8) { + backupTypeSpecCase_ = 0; + backupTypeSpec_ = null; + onChanged(); + } + } else { + if (backupTypeSpecCase_ == 8) { + backupTypeSpecCase_ = 0; + backupTypeSpec_ = null; + } + incrementalBackupSpecBuilder_.clear(); + } + return this; + } + /** + * + * + *
+     * The schedule creates incremental backup chains.
+     * 
+ * + * .google.spanner.admin.database.v1.IncrementalBackupSpec incremental_backup_spec = 8; + * + */ + public com.google.spanner.admin.database.v1.IncrementalBackupSpec.Builder + getIncrementalBackupSpecBuilder() { + return getIncrementalBackupSpecFieldBuilder().getBuilder(); + } + /** + * + * + *
+     * The schedule creates incremental backup chains.
+     * 
+ * + * .google.spanner.admin.database.v1.IncrementalBackupSpec incremental_backup_spec = 8; + * + */ + @java.lang.Override + public com.google.spanner.admin.database.v1.IncrementalBackupSpecOrBuilder + getIncrementalBackupSpecOrBuilder() { + if ((backupTypeSpecCase_ == 8) && (incrementalBackupSpecBuilder_ != null)) { + return incrementalBackupSpecBuilder_.getMessageOrBuilder(); + } else { + if (backupTypeSpecCase_ == 8) { + return (com.google.spanner.admin.database.v1.IncrementalBackupSpec) backupTypeSpec_; + } + return com.google.spanner.admin.database.v1.IncrementalBackupSpec.getDefaultInstance(); + } + } + /** + * + * + *
+     * The schedule creates incremental backup chains.
+     * 
+ * + * .google.spanner.admin.database.v1.IncrementalBackupSpec incremental_backup_spec = 8; + * + */ + private com.google.protobuf.SingleFieldBuilderV3< + com.google.spanner.admin.database.v1.IncrementalBackupSpec, + com.google.spanner.admin.database.v1.IncrementalBackupSpec.Builder, + com.google.spanner.admin.database.v1.IncrementalBackupSpecOrBuilder> + getIncrementalBackupSpecFieldBuilder() { + if (incrementalBackupSpecBuilder_ == null) { + if (!(backupTypeSpecCase_ == 8)) { + backupTypeSpec_ = + com.google.spanner.admin.database.v1.IncrementalBackupSpec.getDefaultInstance(); + } + incrementalBackupSpecBuilder_ = + new com.google.protobuf.SingleFieldBuilderV3< + com.google.spanner.admin.database.v1.IncrementalBackupSpec, + com.google.spanner.admin.database.v1.IncrementalBackupSpec.Builder, + com.google.spanner.admin.database.v1.IncrementalBackupSpecOrBuilder>( + (com.google.spanner.admin.database.v1.IncrementalBackupSpec) backupTypeSpec_, + getParentForChildren(), + isClean()); + backupTypeSpec_ = null; + } + backupTypeSpecCase_ = 8; + onChanged(); + return incrementalBackupSpecBuilder_; + } + private com.google.protobuf.Timestamp updateTime_; private com.google.protobuf.SingleFieldBuilderV3< com.google.protobuf.Timestamp, @@ -2073,7 +2390,7 @@ public com.google.spanner.admin.database.v1.FullBackupSpec.Builder getFullBackup * @return Whether the updateTime field is set. */ public boolean hasUpdateTime() { - return ((bitField0_ & 0x00000020) != 0); + return ((bitField0_ & 0x00000040) != 0); } /** * @@ -2121,7 +2438,7 @@ public Builder setUpdateTime(com.google.protobuf.Timestamp value) { } else { updateTimeBuilder_.setMessage(value); } - bitField0_ |= 0x00000020; + bitField0_ |= 0x00000040; onChanged(); return this; } @@ -2144,7 +2461,7 @@ public Builder setUpdateTime(com.google.protobuf.Timestamp.Builder builderForVal } else { updateTimeBuilder_.setMessage(builderForValue.build()); } - bitField0_ |= 0x00000020; + bitField0_ |= 0x00000040; onChanged(); return this; } @@ -2163,7 +2480,7 @@ public Builder setUpdateTime(com.google.protobuf.Timestamp.Builder builderForVal */ public Builder mergeUpdateTime(com.google.protobuf.Timestamp value) { if (updateTimeBuilder_ == null) { - if (((bitField0_ & 0x00000020) != 0) + if (((bitField0_ & 0x00000040) != 0) && updateTime_ != null && updateTime_ != com.google.protobuf.Timestamp.getDefaultInstance()) { getUpdateTimeBuilder().mergeFrom(value); @@ -2174,7 +2491,7 @@ public Builder mergeUpdateTime(com.google.protobuf.Timestamp value) { updateTimeBuilder_.mergeFrom(value); } if (updateTime_ != null) { - bitField0_ |= 0x00000020; + bitField0_ |= 0x00000040; onChanged(); } return this; @@ -2193,7 +2510,7 @@ public Builder mergeUpdateTime(com.google.protobuf.Timestamp value) { * */ public Builder clearUpdateTime() { - bitField0_ = (bitField0_ & ~0x00000020); + bitField0_ = (bitField0_ & ~0x00000040); updateTime_ = null; if (updateTimeBuilder_ != null) { updateTimeBuilder_.dispose(); @@ -2216,7 +2533,7 @@ public Builder clearUpdateTime() { * */ public com.google.protobuf.Timestamp.Builder getUpdateTimeBuilder() { - bitField0_ |= 0x00000020; + bitField0_ |= 0x00000040; onChanged(); return getUpdateTimeFieldBuilder().getBuilder(); } diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupScheduleOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupScheduleOrBuilder.java index cb1db14d21..128bc441f7 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupScheduleOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupScheduleOrBuilder.java @@ -239,6 +239,45 @@ public interface BackupScheduleOrBuilder */ com.google.spanner.admin.database.v1.FullBackupSpecOrBuilder getFullBackupSpecOrBuilder(); + /** + * + * + *
+   * The schedule creates incremental backup chains.
+   * 
+ * + * .google.spanner.admin.database.v1.IncrementalBackupSpec incremental_backup_spec = 8; + * + * + * @return Whether the incrementalBackupSpec field is set. + */ + boolean hasIncrementalBackupSpec(); + /** + * + * + *
+   * The schedule creates incremental backup chains.
+   * 
+ * + * .google.spanner.admin.database.v1.IncrementalBackupSpec incremental_backup_spec = 8; + * + * + * @return The incrementalBackupSpec. + */ + com.google.spanner.admin.database.v1.IncrementalBackupSpec getIncrementalBackupSpec(); + /** + * + * + *
+   * The schedule creates incremental backup chains.
+   * 
+ * + * .google.spanner.admin.database.v1.IncrementalBackupSpec incremental_backup_spec = 8; + * + */ + com.google.spanner.admin.database.v1.IncrementalBackupSpecOrBuilder + getIncrementalBackupSpecOrBuilder(); + /** * * diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupScheduleProto.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupScheduleProto.java index d2227049ae..9f018585af 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupScheduleProto.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupScheduleProto.java @@ -83,7 +83,7 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { + "/v1/backup.proto\"i\n\022BackupScheduleSpec\022B" + "\n\tcron_spec\030\001 \001(\0132-.google.spanner.admin" + ".database.v1.CrontabSpecH\000B\017\n\rschedule_s" - + "pec\"\310\004\n\016BackupSchedule\022\021\n\004name\030\001 \001(\tB\003\340A" + + "pec\"\244\005\n\016BackupSchedule\022\021\n\004name\030\001 \001(\tB\003\340A" + "\010\022G\n\004spec\030\006 \001(\01324.google.spanner.admin.d" + "atabase.v1.BackupScheduleSpecB\003\340A\001\022:\n\022re" + "tention_duration\030\003 \001(\0132\031.google.protobuf" @@ -91,43 +91,46 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { + "\0132>.google.spanner.admin.database.v1.Cre" + "ateBackupEncryptionConfigB\003\340A\001\022L\n\020full_b" + "ackup_spec\030\007 \001(\01320.google.spanner.admin." - + "database.v1.FullBackupSpecH\000\0224\n\013update_t" - + "ime\030\t \001(\0132\032.google.protobuf.TimestampB\003\340" - + "A\003:\245\001\352A\241\001\n%spanner.googleapis.com/Backup" - + "Schedule\022Wprojects/{project}/instances/{" - + "instance}/databases/{database}/backupSch" - + "edules/{schedule}*\017backupSchedules2\016back" - + "upScheduleB\022\n\020backup_type_spec\"q\n\013Cronta" - + "bSpec\022\021\n\004text\030\001 \001(\tB\003\340A\002\022\026\n\ttime_zone\030\002 " - + "\001(\tB\003\340A\003\0227\n\017creation_window\030\003 \001(\0132\031.goog" - + "le.protobuf.DurationB\003\340A\003\"\307\001\n\033CreateBack" - + "upScheduleRequest\0227\n\006parent\030\001 \001(\tB\'\340A\002\372A" - + "!\n\037spanner.googleapis.com/Database\022\037\n\022ba" - + "ckup_schedule_id\030\002 \001(\tB\003\340A\002\022N\n\017backup_sc" - + "hedule\030\003 \001(\01320.google.spanner.admin.data" - + "base.v1.BackupScheduleB\003\340A\002\"W\n\030GetBackup" - + "ScheduleRequest\022;\n\004name\030\001 \001(\tB-\340A\002\372A\'\n%s" - + "panner.googleapis.com/BackupSchedule\"Z\n\033" - + "DeleteBackupScheduleRequest\022;\n\004name\030\001 \001(" + + "database.v1.FullBackupSpecH\000\022Z\n\027incremen" + + "tal_backup_spec\030\010 \001(\01327.google.spanner.a" + + "dmin.database.v1.IncrementalBackupSpecH\000" + + "\0224\n\013update_time\030\t \001(\0132\032.google.protobuf." + + "TimestampB\003\340A\003:\245\001\352A\241\001\n%spanner.googleapi" + + "s.com/BackupSchedule\022Wprojects/{project}" + + "/instances/{instance}/databases/{databas" + + "e}/backupSchedules/{schedule}*\017backupSch" + + "edules2\016backupScheduleB\022\n\020backup_type_sp" + + "ec\"q\n\013CrontabSpec\022\021\n\004text\030\001 \001(\tB\003\340A\002\022\026\n\t" + + "time_zone\030\002 \001(\tB\003\340A\003\0227\n\017creation_window\030" + + "\003 \001(\0132\031.google.protobuf.DurationB\003\340A\003\"\307\001" + + "\n\033CreateBackupScheduleRequest\0227\n\006parent\030" + + "\001 \001(\tB\'\340A\002\372A!\n\037spanner.googleapis.com/Da" + + "tabase\022\037\n\022backup_schedule_id\030\002 \001(\tB\003\340A\002\022" + + "N\n\017backup_schedule\030\003 \001(\01320.google.spanne" + + "r.admin.database.v1.BackupScheduleB\003\340A\002\"" + + "W\n\030GetBackupScheduleRequest\022;\n\004name\030\001 \001(" + "\tB-\340A\002\372A\'\n%spanner.googleapis.com/Backup" - + "Schedule\"\206\001\n\032ListBackupSchedulesRequest\022" - + "7\n\006parent\030\001 \001(\tB\'\340A\002\372A!\n\037spanner.googlea" - + "pis.com/Database\022\026\n\tpage_size\030\002 \001(\005B\003\340A\001" - + "\022\027\n\npage_token\030\004 \001(\tB\003\340A\001\"\202\001\n\033ListBackup" - + "SchedulesResponse\022J\n\020backup_schedules\030\001 " - + "\003(\01320.google.spanner.admin.database.v1.B" - + "ackupSchedule\022\027\n\017next_page_token\030\002 \001(\t\"\243" - + "\001\n\033UpdateBackupScheduleRequest\022N\n\017backup" - + "_schedule\030\001 \001(\01320.google.spanner.admin.d" - + "atabase.v1.BackupScheduleB\003\340A\002\0224\n\013update" - + "_mask\030\002 \001(\0132\032.google.protobuf.FieldMaskB" - + "\003\340A\002B\205\002\n$com.google.spanner.admin.databa" - + "se.v1B\023BackupScheduleProtoP\001ZFcloud.goog" - + "le.com/go/spanner/admin/database/apiv1/d" - + "atabasepb;databasepb\252\002&Google.Cloud.Span" - + "ner.Admin.Database.V1\312\002&Google\\Cloud\\Spa" - + "nner\\Admin\\Database\\V1\352\002+Google::Cloud::" - + "Spanner::Admin::Database::V1b\006proto3" + + "Schedule\"Z\n\033DeleteBackupScheduleRequest\022" + + ";\n\004name\030\001 \001(\tB-\340A\002\372A\'\n%spanner.googleapi" + + "s.com/BackupSchedule\"\206\001\n\032ListBackupSched" + + "ulesRequest\0227\n\006parent\030\001 \001(\tB\'\340A\002\372A!\n\037spa" + + "nner.googleapis.com/Database\022\026\n\tpage_siz" + + "e\030\002 \001(\005B\003\340A\001\022\027\n\npage_token\030\004 \001(\tB\003\340A\001\"\202\001" + + "\n\033ListBackupSchedulesResponse\022J\n\020backup_" + + "schedules\030\001 \003(\01320.google.spanner.admin.d" + + "atabase.v1.BackupSchedule\022\027\n\017next_page_t" + + "oken\030\002 \001(\t\"\243\001\n\033UpdateBackupScheduleReque" + + "st\022N\n\017backup_schedule\030\001 \001(\01320.google.spa" + + "nner.admin.database.v1.BackupScheduleB\003\340" + + "A\002\0224\n\013update_mask\030\002 \001(\0132\032.google.protobu" + + "f.FieldMaskB\003\340A\002B\205\002\n$com.google.spanner." + + "admin.database.v1B\023BackupScheduleProtoP\001" + + "ZFcloud.google.com/go/spanner/admin/data" + + "base/apiv1/databasepb;databasepb\252\002&Googl" + + "e.Cloud.Spanner.Admin.Database.V1\312\002&Goog" + + "le\\Cloud\\Spanner\\Admin\\Database\\V1\352\002+Goo" + + "gle::Cloud::Spanner::Admin::Database::V1" + + "b\006proto3" }; descriptor = com.google.protobuf.Descriptors.FileDescriptor.internalBuildGeneratedFileFrom( @@ -159,6 +162,7 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { "RetentionDuration", "EncryptionConfig", "FullBackupSpec", + "IncrementalBackupSpec", "UpdateTime", "BackupTypeSpec", }); diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/IncrementalBackupSpec.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/IncrementalBackupSpec.java new file mode 100644 index 0000000000..36a605c8aa --- /dev/null +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/IncrementalBackupSpec.java @@ -0,0 +1,443 @@ +/* + * Copyright 2024 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. + */ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/spanner/admin/database/v1/backup.proto + +// Protobuf Java Version: 3.25.3 +package com.google.spanner.admin.database.v1; + +/** + * + * + *
+ * The specification for incremental backup chains.
+ * An incremental backup stores the delta of changes between a previous
+ * backup and the database contents at a given version time. An
+ * incremental backup chain consists of a full backup and zero or more
+ * successive incremental backups. The first backup created for an
+ * incremental backup chain is always a full backup.
+ * 
+ * + * Protobuf type {@code google.spanner.admin.database.v1.IncrementalBackupSpec} + */ +public final class IncrementalBackupSpec extends com.google.protobuf.GeneratedMessageV3 + implements + // @@protoc_insertion_point(message_implements:google.spanner.admin.database.v1.IncrementalBackupSpec) + IncrementalBackupSpecOrBuilder { + private static final long serialVersionUID = 0L; + // Use IncrementalBackupSpec.newBuilder() to construct. + private IncrementalBackupSpec(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + + private IncrementalBackupSpec() {} + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance(UnusedPrivateParameter unused) { + return new IncrementalBackupSpec(); + } + + public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { + return com.google.spanner.admin.database.v1.BackupProto + .internal_static_google_spanner_admin_database_v1_IncrementalBackupSpec_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.google.spanner.admin.database.v1.BackupProto + .internal_static_google_spanner_admin_database_v1_IncrementalBackupSpec_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.google.spanner.admin.database.v1.IncrementalBackupSpec.class, + com.google.spanner.admin.database.v1.IncrementalBackupSpec.Builder.class); + } + + private byte memoizedIsInitialized = -1; + + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { + getUnknownFields().writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + size += getUnknownFields().getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof com.google.spanner.admin.database.v1.IncrementalBackupSpec)) { + return super.equals(obj); + } + com.google.spanner.admin.database.v1.IncrementalBackupSpec other = + (com.google.spanner.admin.database.v1.IncrementalBackupSpec) obj; + + if (!getUnknownFields().equals(other.getUnknownFields())) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (29 * hash) + getUnknownFields().hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static com.google.spanner.admin.database.v1.IncrementalBackupSpec parseFrom( + java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + + public static com.google.spanner.admin.database.v1.IncrementalBackupSpec parseFrom( + java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + + public static com.google.spanner.admin.database.v1.IncrementalBackupSpec parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + + public static com.google.spanner.admin.database.v1.IncrementalBackupSpec parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + + public static com.google.spanner.admin.database.v1.IncrementalBackupSpec parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + + public static com.google.spanner.admin.database.v1.IncrementalBackupSpec parseFrom( + byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + + public static com.google.spanner.admin.database.v1.IncrementalBackupSpec parseFrom( + java.io.InputStream input) throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseWithIOException(PARSER, input); + } + + public static com.google.spanner.admin.database.v1.IncrementalBackupSpec parseFrom( + java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseWithIOException( + PARSER, input, extensionRegistry); + } + + public static com.google.spanner.admin.database.v1.IncrementalBackupSpec parseDelimitedFrom( + java.io.InputStream input) throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseDelimitedWithIOException(PARSER, input); + } + + public static com.google.spanner.admin.database.v1.IncrementalBackupSpec parseDelimitedFrom( + java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseDelimitedWithIOException( + PARSER, input, extensionRegistry); + } + + public static com.google.spanner.admin.database.v1.IncrementalBackupSpec parseFrom( + com.google.protobuf.CodedInputStream input) throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseWithIOException(PARSER, input); + } + + public static com.google.spanner.admin.database.v1.IncrementalBackupSpec parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseWithIOException( + PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { + return newBuilder(); + } + + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + + public static Builder newBuilder( + com.google.spanner.admin.database.v1.IncrementalBackupSpec prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * + * + *
+   * The specification for incremental backup chains.
+   * An incremental backup stores the delta of changes between a previous
+   * backup and the database contents at a given version time. An
+   * incremental backup chain consists of a full backup and zero or more
+   * successive incremental backups. The first backup created for an
+   * incremental backup chain is always a full backup.
+   * 
+ * + * Protobuf type {@code google.spanner.admin.database.v1.IncrementalBackupSpec} + */ + public static final class Builder extends com.google.protobuf.GeneratedMessageV3.Builder + implements + // @@protoc_insertion_point(builder_implements:google.spanner.admin.database.v1.IncrementalBackupSpec) + com.google.spanner.admin.database.v1.IncrementalBackupSpecOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { + return com.google.spanner.admin.database.v1.BackupProto + .internal_static_google_spanner_admin_database_v1_IncrementalBackupSpec_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.google.spanner.admin.database.v1.BackupProto + .internal_static_google_spanner_admin_database_v1_IncrementalBackupSpec_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.google.spanner.admin.database.v1.IncrementalBackupSpec.class, + com.google.spanner.admin.database.v1.IncrementalBackupSpec.Builder.class); + } + + // Construct using com.google.spanner.admin.database.v1.IncrementalBackupSpec.newBuilder() + private Builder() {} + + private Builder(com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + } + + @java.lang.Override + public Builder clear() { + super.clear(); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { + return com.google.spanner.admin.database.v1.BackupProto + .internal_static_google_spanner_admin_database_v1_IncrementalBackupSpec_descriptor; + } + + @java.lang.Override + public com.google.spanner.admin.database.v1.IncrementalBackupSpec getDefaultInstanceForType() { + return com.google.spanner.admin.database.v1.IncrementalBackupSpec.getDefaultInstance(); + } + + @java.lang.Override + public com.google.spanner.admin.database.v1.IncrementalBackupSpec build() { + com.google.spanner.admin.database.v1.IncrementalBackupSpec result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public com.google.spanner.admin.database.v1.IncrementalBackupSpec buildPartial() { + com.google.spanner.admin.database.v1.IncrementalBackupSpec result = + new com.google.spanner.admin.database.v1.IncrementalBackupSpec(this); + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, java.lang.Object value) { + return super.setField(field, value); + } + + @java.lang.Override + public Builder clearField(com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + + @java.lang.Override + public Builder clearOneof(com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, java.lang.Object value) { + return super.addRepeatedField(field, value); + } + + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof com.google.spanner.admin.database.v1.IncrementalBackupSpec) { + return mergeFrom((com.google.spanner.admin.database.v1.IncrementalBackupSpec) other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(com.google.spanner.admin.database.v1.IncrementalBackupSpec other) { + if (other == com.google.spanner.admin.database.v1.IncrementalBackupSpec.getDefaultInstance()) + return this; + this.mergeUnknownFields(other.getUnknownFields()); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: + { + if (!super.parseUnknownField(input, extensionRegistry, tag)) { + done = true; // was an endgroup tag + } + break; + } // default: + } // switch (tag) + } // while (!done) + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.unwrapIOException(); + } finally { + onChanged(); + } // finally + return this; + } + + @java.lang.Override + public final Builder setUnknownFields(final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + // @@protoc_insertion_point(builder_scope:google.spanner.admin.database.v1.IncrementalBackupSpec) + } + + // @@protoc_insertion_point(class_scope:google.spanner.admin.database.v1.IncrementalBackupSpec) + private static final com.google.spanner.admin.database.v1.IncrementalBackupSpec DEFAULT_INSTANCE; + + static { + DEFAULT_INSTANCE = new com.google.spanner.admin.database.v1.IncrementalBackupSpec(); + } + + public static com.google.spanner.admin.database.v1.IncrementalBackupSpec getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + @java.lang.Override + public IncrementalBackupSpec parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + Builder builder = newBuilder(); + try { + builder.mergeFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(builder.buildPartial()); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException(e) + .setUnfinishedMessage(builder.buildPartial()); + } + return builder.buildPartial(); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public com.google.spanner.admin.database.v1.IncrementalBackupSpec getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } +} diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/IncrementalBackupSpecOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/IncrementalBackupSpecOrBuilder.java new file mode 100644 index 0000000000..fa0ee3f7e7 --- /dev/null +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/IncrementalBackupSpecOrBuilder.java @@ -0,0 +1,25 @@ +/* + * Copyright 2024 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. + */ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/spanner/admin/database/v1/backup.proto + +// Protobuf Java Version: 3.25.3 +package com.google.spanner.admin.database.v1; + +public interface IncrementalBackupSpecOrBuilder + extends + // @@protoc_insertion_point(interface_extends:google.spanner.admin.database.v1.IncrementalBackupSpec) + com.google.protobuf.MessageOrBuilder {} diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/proto/google/spanner/admin/database/v1/backup.proto b/proto-google-cloud-spanner-admin-database-v1/src/main/proto/google/spanner/admin/database/v1/backup.proto index f684a4c605..842ab0ff1e 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/proto/google/spanner/admin/database/v1/backup.proto +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/proto/google/spanner/admin/database/v1/backup.proto @@ -103,6 +103,24 @@ message Backup { // Output only. Size of the backup in bytes. int64 size_bytes = 5 [(google.api.field_behavior) = OUTPUT_ONLY]; + // Output only. The number of bytes that will be freed by deleting this + // backup. This value will be zero if, for example, this backup is part of an + // incremental backup chain and younger backups in the chain require that we + // keep its data. For backups not in an incremental backup chain, this is + // always the size of the backup. This value may change if backups on the same + // chain get created, deleted or expired. + int64 freeable_size_bytes = 15 [(google.api.field_behavior) = OUTPUT_ONLY]; + + // Output only. For a backup in an incremental backup chain, this is the + // storage space needed to keep the data that has changed since the previous + // backup. For all other backups, this is always the size of the backup. This + // value may change if backups on the same chain get deleted or expired. + // + // This field can be used to calculate the total storage space used by a set + // of backups. For example, the total space used by all backups of a database + // can be computed by summing up this field. + int64 exclusive_size_bytes = 16 [(google.api.field_behavior) = OUTPUT_ONLY]; + // Output only. The current state of the backup. State state = 6 [(google.api.field_behavior) = OUTPUT_ONLY]; @@ -168,6 +186,23 @@ message Backup { // single backup schedule URI associated with creating this backup. repeated string backup_schedules = 14 [(google.api.field_behavior) = OUTPUT_ONLY]; + + // Output only. Populated only for backups in an incremental backup chain. + // Backups share the same chain id if and only if they belong to the same + // incremental backup chain. Use this field to determine which backups are + // part of the same incremental backup chain. The ordering of backups in the + // chain can be determined by ordering the backup `version_time`. + string incremental_backup_chain_id = 17 + [(google.api.field_behavior) = OUTPUT_ONLY]; + + // Output only. Data deleted at a time older than this is guaranteed not to be + // retained in order to support this backup. For a backup in an incremental + // backup chain, this is the version time of the oldest backup that exists or + // ever existed in the chain. For all other backups, this is the version time + // of the backup. This field can be used to understand what data is being + // retained by the backup system. + google.protobuf.Timestamp oldest_version_time = 18 + [(google.api.field_behavior) = OUTPUT_ONLY]; } // The request for @@ -705,3 +740,11 @@ message CopyBackupEncryptionConfig { // A full backup stores the entire contents of the database at a given // version time. message FullBackupSpec {} + +// The specification for incremental backup chains. +// An incremental backup stores the delta of changes between a previous +// backup and the database contents at a given version time. An +// incremental backup chain consists of a full backup and zero or more +// successive incremental backups. The first backup created for an +// incremental backup chain is always a full backup. +message IncrementalBackupSpec {} diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/proto/google/spanner/admin/database/v1/backup_schedule.proto b/proto-google-cloud-spanner-admin-database-v1/src/main/proto/google/spanner/admin/database/v1/backup_schedule.proto index 9ef4587f81..c9b5e7e3f4 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/proto/google/spanner/admin/database/v1/backup_schedule.proto +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/proto/google/spanner/admin/database/v1/backup_schedule.proto @@ -83,6 +83,9 @@ message BackupSchedule { oneof backup_type_spec { // The schedule creates only full backups. FullBackupSpec full_backup_spec = 7; + + // The schedule creates incremental backup chains. + IncrementalBackupSpec incremental_backup_spec = 8; } // Output only. The timestamp at which the schedule was last updated. From bc48bf212e37441221b3b6c8742b07ff601f6c41 Mon Sep 17 00:00:00 2001 From: Varun Naik Date: Mon, 5 Aug 2024 21:52:44 -0700 Subject: [PATCH 08/38] feat(spanner): add samples for instance partitions (#3221) * feat(spanner): add samples for instance partitions * Lint * Lint --- .../CreateInstancePartitionSample.java | 80 +++++++++++++++++++ .../CreateInstancePartitionSampleIT.java | 55 +++++++++++++ 2 files changed, 135 insertions(+) create mode 100644 samples/snippets/src/main/java/com/example/spanner/CreateInstancePartitionSample.java create mode 100644 samples/snippets/src/test/java/com/example/spanner/CreateInstancePartitionSampleIT.java diff --git a/samples/snippets/src/main/java/com/example/spanner/CreateInstancePartitionSample.java b/samples/snippets/src/main/java/com/example/spanner/CreateInstancePartitionSample.java new file mode 100644 index 0000000000..0e547bdaf7 --- /dev/null +++ b/samples/snippets/src/main/java/com/example/spanner/CreateInstancePartitionSample.java @@ -0,0 +1,80 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.spanner; + +// [START spanner_create_instance_partition] + +import com.google.cloud.spanner.Spanner; +import com.google.cloud.spanner.SpannerOptions; +import com.google.cloud.spanner.admin.instance.v1.InstanceAdminClient; +import com.google.spanner.admin.instance.v1.CreateInstancePartitionRequest; +import com.google.spanner.admin.instance.v1.InstanceConfigName; +import com.google.spanner.admin.instance.v1.InstanceName; +import com.google.spanner.admin.instance.v1.InstancePartition; +import java.util.concurrent.ExecutionException; + +class CreateInstancePartitionSample { + + static void createInstancePartition() { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project"; + String instanceId = "my-instance"; + String instancePartitionId = "my-instance-partition"; + createInstancePartition(projectId, instanceId, instancePartitionId); + } + + static void createInstancePartition( + String projectId, String instanceId, String instancePartitionId) { + // Set instance partition configuration. + int nodeCount = 1; + String displayName = "Descriptive name"; + + // Create an InstancePartition object that will be used to create the instance partition. + InstancePartition instancePartition = + InstancePartition.newBuilder() + .setDisplayName(displayName) + .setNodeCount(nodeCount) + .setConfig(InstanceConfigName.of(projectId, "nam3").toString()) + .build(); + + try (Spanner spanner = + SpannerOptions.newBuilder().setProjectId(projectId).build().getService(); + InstanceAdminClient instanceAdminClient = spanner.createInstanceAdminClient()) { + + // Wait for the createInstancePartition operation to finish. + InstancePartition createdInstancePartition = + instanceAdminClient + .createInstancePartitionAsync( + CreateInstancePartitionRequest.newBuilder() + .setParent(InstanceName.of(projectId, instanceId).toString()) + .setInstancePartitionId(instancePartitionId) + .setInstancePartition(instancePartition) + .build()) + .get(); + System.out.printf( + "Instance partition %s was successfully created%n", createdInstancePartition.getName()); + } catch (ExecutionException e) { + System.out.printf( + "Error: Creating instance partition %s failed with error message %s%n", + instancePartition.getName(), e.getMessage()); + } catch (InterruptedException e) { + System.out.println( + "Error: Waiting for createInstancePartition operation to finish was interrupted"); + } + } +} +// [END spanner_create_instance_partition] diff --git a/samples/snippets/src/test/java/com/example/spanner/CreateInstancePartitionSampleIT.java b/samples/snippets/src/test/java/com/example/spanner/CreateInstancePartitionSampleIT.java new file mode 100644 index 0000000000..3038d29750 --- /dev/null +++ b/samples/snippets/src/test/java/com/example/spanner/CreateInstancePartitionSampleIT.java @@ -0,0 +1,55 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.spanner; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.cloud.spanner.InstanceAdminClient; +import com.google.cloud.spanner.InstanceConfigId; +import com.google.cloud.spanner.InstanceId; +import com.google.cloud.spanner.InstanceInfo; +import com.google.spanner.admin.instance.v1.InstancePartitionName; +import org.junit.Test; + +public class CreateInstancePartitionSampleIT extends SampleTestBaseV2 { + + @Test + public void testCreateInstancePartition() throws Exception { + String instanceId = idGenerator.generateInstanceId(); + InstanceAdminClient instanceAdminClient = spanner.getInstanceAdminClient(); + instanceAdminClient + .createInstance( + InstanceInfo.newBuilder(InstanceId.of(projectId, instanceId)) + .setDisplayName("Geo-partitioning test instance") + .setInstanceConfigId(InstanceConfigId.of(projectId, "regional-us-central1")) + .setNodeCount(1) + .build()) + .get(); + + String instancePartitionId = "my-instance-partition"; + String out = + SampleRunner.runSample( + () -> + CreateInstancePartitionSample.createInstancePartition( + projectId, instanceId, instancePartitionId)); + assertThat(out) + .contains( + String.format( + "Instance partition %s", + InstancePartitionName.of(projectId, instanceId, instancePartitionId).toString())); + } +} From db875037a61cd627b4497768025a10a593681ca7 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 6 Aug 2024 07:32:22 +0200 Subject: [PATCH 09/38] build(deps): update dependency org.apache.maven.plugins:maven-failsafe-plugin to v3.3.1 (#3211) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [org.apache.maven.plugins:maven-failsafe-plugin](https://maven.apache.org/surefire/) | `3.3.0` -> `3.3.1` | [![age](https://developer.mend.io/api/mc/badges/age/maven/org.apache.maven.plugins:maven-failsafe-plugin/3.3.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/maven/org.apache.maven.plugins:maven-failsafe-plugin/3.3.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/maven/org.apache.maven.plugins:maven-failsafe-plugin/3.3.0/3.3.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/org.apache.maven.plugins:maven-failsafe-plugin/3.3.0/3.3.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View the [repository job log](https://developer.mend.io/github/googleapis/java-spanner). --- google-cloud-spanner-executor/pom.xml | 2 +- samples/install-without-bom/pom.xml | 2 +- samples/snapshot/pom.xml | 2 +- samples/snippets/pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/google-cloud-spanner-executor/pom.xml b/google-cloud-spanner-executor/pom.xml index 6df4fe5830..dc4f6d81ac 100644 --- a/google-cloud-spanner-executor/pom.xml +++ b/google-cloud-spanner-executor/pom.xml @@ -188,7 +188,7 @@ org.apache.maven.plugins maven-failsafe-plugin - 3.3.0 + 3.3.1 diff --git a/samples/install-without-bom/pom.xml b/samples/install-without-bom/pom.xml index 79d9c66588..8d8fa90b81 100644 --- a/samples/install-without-bom/pom.xml +++ b/samples/install-without-bom/pom.xml @@ -145,7 +145,7 @@ org.apache.maven.plugins maven-failsafe-plugin - 3.3.0 + 3.3.1 java-client-integration-tests diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml index 3f37886a32..cd4be6e3dc 100644 --- a/samples/snapshot/pom.xml +++ b/samples/snapshot/pom.xml @@ -144,7 +144,7 @@ org.apache.maven.plugins maven-failsafe-plugin - 3.3.0 + 3.3.1 java-client-integration-tests diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml index ced7df0a37..3f482a12b0 100644 --- a/samples/snippets/pom.xml +++ b/samples/snippets/pom.xml @@ -175,7 +175,7 @@ org.apache.maven.plugins maven-failsafe-plugin - 3.3.0 + 3.3.1 java-client-integration-tests From 065cd489964aaee42fffe1e71327906bde907205 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 6 Aug 2024 16:29:28 +0200 Subject: [PATCH 10/38] deps: update dependency com.google.auto.value:auto-value-annotations to v1.11.0 (#3191) --- benchmarks/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index 14131d2342..3a67e81a7c 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -102,7 +102,7 @@ com.google.auto.value auto-value-annotations - 1.10.4 + 1.11.0 com.kohlschutter.junixsocket From d2d942ed98984b1bd088e1fbeb1008aa9a6a0e3a Mon Sep 17 00:00:00 2001 From: cloud-java-bot <122572305+cloud-java-bot@users.noreply.github.com> Date: Tue, 6 Aug 2024 11:49:23 -0400 Subject: [PATCH 11/38] chore: Update generation configuration at Tue Aug 6 02:15:55 UTC 2024 (#3235) --- generation_config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generation_config.yaml b/generation_config.yaml index 94e11368e5..07eb1e3ac0 100644 --- a/generation_config.yaml +++ b/generation_config.yaml @@ -1,5 +1,5 @@ gapic_generator_version: 2.43.0 -googleapis_commitish: bc05924644a4bb93c0ac5973a07b83387a93b71f +googleapis_commitish: 7314e20f5e3b2550b2e10a8c53f58ae57c511773 libraries_bom_version: 26.43.0 libraries: - api_shortname: spanner From da177d539cc6bf01218406c38df6926f2bcc29ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Olav=20L=C3=B8ite?= Date: Tue, 6 Aug 2024 18:32:35 +0200 Subject: [PATCH 12/38] chore: unflake SavepointMockServerTest (#3237) * chore: unflake SavepointMockServerTest * fix: use separate tag to verify no keep-alive requests --- .../connection/ReadWriteTransaction.java | 5 +- .../connection/SavepointMockServerTest.java | 46 ++++++------------- 2 files changed, 17 insertions(+), 34 deletions(-) diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ReadWriteTransaction.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ReadWriteTransaction.java index 520a2e180e..0362ffc205 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ReadWriteTransaction.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ReadWriteTransaction.java @@ -461,7 +461,10 @@ public void run() { CallType.SYNC, SELECT1_STATEMENT, AnalyzeMode.NONE, - Options.tag("connection.transaction-keep-alive")); + Options.tag( + System.getProperty( + "spanner.connection.keep_alive_query_tag", + "connection.transaction-keep-alive"))); future.addListener( ReadWriteTransaction.this::maybeScheduleKeepAlivePing, MoreExecutors.directExecutor()); } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SavepointMockServerTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SavepointMockServerTest.java index e615b78e9d..3197248162 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SavepointMockServerTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SavepointMockServerTest.java @@ -682,14 +682,16 @@ public void testRollbackToSavepointWithoutInternalRetriesInReadOnlyTransaction() @Test public void testKeepAlive() throws InterruptedException, TimeoutException { + String keepAliveTag = "test_keep_alive_tag"; System.setProperty("spanner.connection.keep_alive_interval_millis", "1"); + System.setProperty("spanner.connection.keep_alive_query_tag", keepAliveTag); try (Connection connection = createConnection()) { connection.setSavepointSupport(SavepointSupport.ENABLED); connection.setKeepTransactionAlive(true); // Start a transaction by executing a statement. connection.execute(INSERT_STATEMENT); // Verify that we get a keep-alive request. - verifyHasKeepAliveRequest(); + verifyHasKeepAliveRequest(keepAliveTag); // Set a savepoint, execute another statement, and rollback to the savepoint. // The keep-alive should not be sent after the transaction has been rolled back to the // savepoint. @@ -697,38 +699,22 @@ public void testKeepAlive() throws InterruptedException, TimeoutException { connection.execute(INSERT_STATEMENT); connection.rollbackToSavepoint("s1"); mockSpanner.waitForRequestsToContain(RollbackRequest.class, 1000L); - // Wait for up to 2 milliseconds to make sure that any keep-alive requests that were in flight - // have finished. - try { - mockSpanner.waitForRequestsToContain( - r -> { - if (!(r instanceof ExecuteSqlRequest)) { - return false; - } - ExecuteSqlRequest request = (ExecuteSqlRequest) r; - return request.getSql().equals("SELECT 1") - && request - .getRequestOptions() - .getRequestTag() - .equals("connection.transaction-keep-alive"); - }, - 2L); - } catch (TimeoutException ignore) { - } + String keepAliveTagAfterRollback = "test_keep_alive_tag_after_rollback"; + System.setProperty("spanner.connection.keep_alive_query_tag", keepAliveTagAfterRollback); - // Verify that we don't get any keep-alive requests from this point. - mockSpanner.clearRequests(); + // Verify that we don't get any new keep-alive requests from this point. Thread.sleep(2L); - assertEquals(0, countKeepAliveRequest()); + assertEquals(0, countKeepAliveRequest(keepAliveTagAfterRollback)); // Resume the transaction and verify that we get a keep-alive again. connection.execute(INSERT_STATEMENT); - verifyHasKeepAliveRequest(); + verifyHasKeepAliveRequest(keepAliveTagAfterRollback); } finally { System.clearProperty("spanner.connection.keep_alive_interval_millis"); + System.clearProperty("spanner.connection.keep_alive_query_tag"); } } - private void verifyHasKeepAliveRequest() throws InterruptedException, TimeoutException { + private void verifyHasKeepAliveRequest(String tag) throws InterruptedException, TimeoutException { mockSpanner.waitForRequestsToContain( r -> { if (!(r instanceof ExecuteSqlRequest)) { @@ -736,23 +722,17 @@ private void verifyHasKeepAliveRequest() throws InterruptedException, TimeoutExc } ExecuteSqlRequest request = (ExecuteSqlRequest) r; return request.getSql().equals("SELECT 1") - && request - .getRequestOptions() - .getRequestTag() - .equals("connection.transaction-keep-alive"); + && request.getRequestOptions().getRequestTag().equals(tag); }, 1000L); } - private long countKeepAliveRequest() { + private long countKeepAliveRequest(String tag) { return mockSpanner.getRequestsOfType(ExecuteSqlRequest.class).stream() .filter( request -> request.getSql().equals("SELECT 1") - && request - .getRequestOptions() - .getRequestTag() - .equals("connection.transaction-keep-alive")) + && request.getRequestOptions().getRequestTag().equals(tag)) .count(); } } From cf2e8691bdced6edf3c7d482743132f9ee27a911 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Olav=20L=C3=B8ite?= Date: Tue, 6 Aug 2024 18:32:57 +0200 Subject: [PATCH 13/38] chore: unflake SessionPoolOptionsTest (#3238) Fixes #3220 --- .../com/google/cloud/spanner/SessionPoolOptionsTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolOptionsTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolOptionsTest.java index 82cc5f8ea3..9b15ddea13 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolOptionsTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolOptionsTest.java @@ -332,11 +332,11 @@ public void testToBuilder() { .build()); assertToBuilderRoundtrip( SessionPoolOptions.newBuilder() - .setMaxSessions(ThreadLocalRandom.current().nextInt(1000)) + .setMaxSessions(ThreadLocalRandom.current().nextInt(1, 1000)) .build()); assertToBuilderRoundtrip( SessionPoolOptions.newBuilder() - .setIncStep(ThreadLocalRandom.current().nextInt(1000)) + .setIncStep(ThreadLocalRandom.current().nextInt(1, 1000)) .build()); assertToBuilderRoundtrip( SessionPoolOptions.newBuilder() @@ -393,7 +393,7 @@ public void testToBuilder() { assertToBuilderRoundtrip( SessionPoolOptions.newBuilder() .setAcquireSessionTimeout( - Duration.ofMillis(ThreadLocalRandom.current().nextLong(10000))) + Duration.ofMillis(ThreadLocalRandom.current().nextLong(1, 10000))) .build()); assertToBuilderRoundtrip( SessionPoolOptions.newBuilder() From ca7e7ead7ea47999a63dfc8584e5c2bad090adc0 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 6 Aug 2024 19:11:04 +0200 Subject: [PATCH 14/38] chore(deps): update dependency com.google.cloud:libraries-bom to v26.43.0 (#3190) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore(deps): update dependency com.google.cloud:libraries-bom to v26.42.0 * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --------- Co-authored-by: Owl Bot Co-authored-by: Knut Olav Løite --- README.md | 2 +- samples/native-image/pom.xml | 2 +- samples/snippets/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0d4db4498e..ec8751ec07 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ If you are using Maven with [BOM][libraries-bom], add this to your pom.xml file: com.google.cloud libraries-bom - 26.39.0 + 26.43.0 pom import diff --git a/samples/native-image/pom.xml b/samples/native-image/pom.xml index e1cedfbafa..423ae4bf26 100644 --- a/samples/native-image/pom.xml +++ b/samples/native-image/pom.xml @@ -29,7 +29,7 @@ com.google.cloud libraries-bom - 26.39.0 + 26.43.0 pom import diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml index 3f482a12b0..7774371d52 100644 --- a/samples/snippets/pom.xml +++ b/samples/snippets/pom.xml @@ -34,7 +34,7 @@ com.google.cloud libraries-bom - 26.39.0 + 26.43.0 pom import From 2024e182c07e77fbaa0386efe636c0c716a06900 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 6 Aug 2024 19:11:30 +0200 Subject: [PATCH 15/38] chore(deps): update dependency com.google.cloud:google-cloud-spanner to v6.69.0 (#3189) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore(deps): update dependency com.google.cloud:google-cloud-spanner to v6.69.0 * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --------- Co-authored-by: Owl Bot Co-authored-by: Knut Olav Løite --- README.md | 2 +- benchmarks/pom.xml | 2 +- samples/install-without-bom/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ec8751ec07..352b0c4496 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ If you are using Maven without the BOM, add this to your dependencies: com.google.cloud google-cloud-spanner - 6.67.0 + 6.71.0 ``` diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index 3a67e81a7c..773e2116a0 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -92,7 +92,7 @@ com.google.cloud google-cloud-spanner - 6.67.0 + 6.71.0 commons-cli diff --git a/samples/install-without-bom/pom.xml b/samples/install-without-bom/pom.xml index 8d8fa90b81..a390d0f19b 100644 --- a/samples/install-without-bom/pom.xml +++ b/samples/install-without-bom/pom.xml @@ -33,7 +33,7 @@ com.google.cloud google-cloud-spanner - 6.67.0 + 6.71.0 From fedac3f6ea2ff71e5bc73f3e0b1702be72a16995 Mon Sep 17 00:00:00 2001 From: rahul2393 Date: Tue, 6 Aug 2024 23:45:44 +0530 Subject: [PATCH 16/38] build: run graalvm integration tests on emulator (#3198) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * build: run graalvm integration tests on emulator * fix build * build: add same TODO as in the JDBC driver --------- Co-authored-by: Knut Olav Løite --- .kokoro/build.sh | 15 +++++++++++++++ .../google/cloud/spanner/IntegrationTestEnv.java | 4 ++++ 2 files changed, 19 insertions(+) diff --git a/.kokoro/build.sh b/.kokoro/build.sh index d3eaf9922b..f8ae5a96f3 100755 --- a/.kokoro/build.sh +++ b/.kokoro/build.sh @@ -48,6 +48,16 @@ if [[ ! -z "${GOOGLE_APPLICATION_CREDENTIALS}" && "${GOOGLE_APPLICATION_CREDENTI export GOOGLE_APPLICATION_CREDENTIALS=$(realpath ${KOKORO_GFILE_DIR}/${GOOGLE_APPLICATION_CREDENTIALS}) fi +# Start the Spanner emulator if the environment variable for it has been set. +# TODO: Change if statement once the env var can be set in the config. +#if [[ ! -z "${SPANNER_EMULATOR_HOST}" ]]; then +if [[ "$JOB_TYPE" == "graalvm" ]] || [[ "$JOB_TYPE" == "graalvm17" ]]; then + echo "Starting emulator" + export SPANNER_EMULATOR_HOST=localhost:9010 + docker pull gcr.io/cloud-spanner-emulator/emulator + docker run -d --rm --name spanner-emulator -p 9010:9010 -p 9020:9020 gcr.io/cloud-spanner-emulator/emulator +fi + # Kokoro integration test uses both JDK 11 and JDK 8. We ensure the generated class files # are compatible with Java 8 when running tests. if [ -n "${JAVA8_HOME}" ]; then @@ -233,6 +243,11 @@ clirr) ;; esac +if [[ ! -z "${SPANNER_EMULATOR_HOST}" ]]; then + echo "Stopping emulator" + docker container stop spanner-emulator +fi + if [ "${REPORT_COVERAGE}" == "true" ] then bash ${KOKORO_GFILE_DIR}/codecov.sh diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/IntegrationTestEnv.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/IntegrationTestEnv.java index 6dd9c29e23..efb7ff59cc 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/IntegrationTestEnv.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/IntegrationTestEnv.java @@ -87,6 +87,10 @@ protected void initializeConfig() throw new NullPointerException("Property " + TEST_ENV_CONFIG_CLASS_NAME + " needs to be set"); } Class configClass; + if (EmulatorSpannerHelper.isUsingEmulator()) { + // Make sure that we use an owned instance on the emulator. + System.setProperty(TEST_INSTANCE_PROPERTY, ""); + } configClass = (Class) Class.forName(CONFIG_CLASS); config = configClass.newInstance(); } From 85bf5cff58d421e805a55bebeccdd315e8e212bd Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 6 Aug 2024 20:16:41 +0200 Subject: [PATCH 17/38] build(deps): update dependency org.codehaus.mojo:build-helper-maven-plugin to v3.6.0 (#3122) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * build(deps): update dependency org.codehaus.mojo:build-helper-maven-plugin to v3.6.0 * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --------- Co-authored-by: Owl Bot Co-authored-by: Knut Olav Løite --- samples/install-without-bom/pom.xml | 2 +- samples/snapshot/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/install-without-bom/pom.xml b/samples/install-without-bom/pom.xml index a390d0f19b..0b5d3480ae 100644 --- a/samples/install-without-bom/pom.xml +++ b/samples/install-without-bom/pom.xml @@ -116,7 +116,7 @@ org.codehaus.mojo build-helper-maven-plugin - 3.5.0 + 3.6.0 add-snippets-source diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml index cd4be6e3dc..7f72f2a5ec 100644 --- a/samples/snapshot/pom.xml +++ b/samples/snapshot/pom.xml @@ -115,7 +115,7 @@ org.codehaus.mojo build-helper-maven-plugin - 3.5.0 + 3.6.0 add-snippets-source From 93a6899df01fa4b8bff849b5dcb904190561ea2f Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 6 Aug 2024 20:17:56 +0200 Subject: [PATCH 18/38] build(deps): update dependency org.sonatype.plugins:nexus-staging-maven-plugin to v1.7.0 (#3188) --- samples/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/pom.xml b/samples/pom.xml index e99ce19e6b..07c91c62ad 100644 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -48,7 +48,7 @@ org.sonatype.plugins nexus-staging-maven-plugin - 1.6.13 + 1.7.0 true From a2dc4201a16956898c9313cf467597043840c069 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 6 Aug 2024 20:18:52 +0200 Subject: [PATCH 19/38] build(deps): update dependency org.apache.maven.plugins:maven-project-info-reports-plugin to v3.6.2 (#3182) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1be1af7640..af104e9200 100644 --- a/pom.xml +++ b/pom.xml @@ -171,7 +171,7 @@ org.apache.maven.plugins maven-project-info-reports-plugin - 3.5.0 + 3.6.2 From 0f25ddcf11fae763c723099e7d8bb9891985c635 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 6 Aug 2024 20:19:29 +0200 Subject: [PATCH 20/38] build(deps): update dependency org.apache.maven.plugins:maven-checkstyle-plugin to v3.4.0 (#3185) --- samples/snippets/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml index 7774371d52..b0575d5ea9 100644 --- a/samples/snippets/pom.xml +++ b/samples/snippets/pom.xml @@ -192,7 +192,7 @@ org.apache.maven.plugins maven-checkstyle-plugin - 3.3.1 + 3.4.0 **/SingerProto.java From 8eee15da8c2c9d7dbbf201b8b2de81850081f37f Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 6 Aug 2024 20:21:00 +0200 Subject: [PATCH 21/38] build(deps): update dependency org.apache.maven.plugins:maven-jar-plugin to v3.4.2 (#3183) --- samples/native-image/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/native-image/pom.xml b/samples/native-image/pom.xml index 423ae4bf26..4eae18226c 100644 --- a/samples/native-image/pom.xml +++ b/samples/native-image/pom.xml @@ -62,7 +62,7 @@ org.apache.maven.plugins maven-jar-plugin - 3.4.1 + 3.4.2 From bb9f8ee4fd426b13d7a312aff28125e485dc2d60 Mon Sep 17 00:00:00 2001 From: Sri Harsha CH <57220027+harshachinta@users.noreply.github.com> Date: Wed, 7 Aug 2024 00:12:04 +0530 Subject: [PATCH 22/38] chore(spanner): Update instance region (#3228) --- .../java/com/google/cloud/spanner/IntegrationTestEnv.java | 2 +- .../main/java/com/example/spanner/InstanceOperations.java | 2 +- .../java/com/example/spanner/CreateInstanceExample.java | 6 +++--- .../spanner/CreateInstanceWithAutoscalingConfigExample.java | 2 +- .../spanner/CreateInstanceWithProcessingUnitsExample.java | 2 +- .../spanner/admin/archived/CreateInstanceExample.java | 2 +- .../CreateInstanceWithAutoscalingConfigExample.java | 2 +- .../archived/CreateInstanceWithProcessingUnitsExample.java | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/IntegrationTestEnv.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/IntegrationTestEnv.java index efb7ff59cc..2c6f886522 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/IntegrationTestEnv.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/IntegrationTestEnv.java @@ -147,7 +147,7 @@ protected void after() { private void initializeInstance(InstanceId instanceId) throws Exception { InstanceConfig instanceConfig; try { - instanceConfig = instanceAdminClient.getInstanceConfig("regional-us-central1"); + instanceConfig = instanceAdminClient.getInstanceConfig("regional-us-east4"); } catch (Throwable ignore) { instanceConfig = Iterators.get(instanceAdminClient.listInstanceConfigs().iterateAll().iterator(), 0, null); diff --git a/samples/native-image/src/main/java/com/example/spanner/InstanceOperations.java b/samples/native-image/src/main/java/com/example/spanner/InstanceOperations.java index 75efd6b45b..cbda19236c 100644 --- a/samples/native-image/src/main/java/com/example/spanner/InstanceOperations.java +++ b/samples/native-image/src/main/java/com/example/spanner/InstanceOperations.java @@ -35,7 +35,7 @@ static void createTestInstance( InstanceInfo instanceInfo = InstanceInfo.newBuilder(InstanceId.of(projectId, instanceId)) - .setInstanceConfigId(InstanceConfigId.of(projectId, "regional-us-central1")) + .setInstanceConfigId(InstanceConfigId.of(projectId, "regional-us-east4")) .setNodeCount(1) .setDisplayName(instanceId) .build(); diff --git a/samples/snippets/src/main/java/com/example/spanner/CreateInstanceExample.java b/samples/snippets/src/main/java/com/example/spanner/CreateInstanceExample.java index b53727ba6d..0bfb3a54c8 100644 --- a/samples/snippets/src/main/java/com/example/spanner/CreateInstanceExample.java +++ b/samples/snippets/src/main/java/com/example/spanner/CreateInstanceExample.java @@ -47,9 +47,9 @@ static void createInstance(String projectId, String instanceId) { .setDisplayName(displayName) .setNodeCount(nodeCount) .setConfig( - InstanceConfigName.of(projectId, "regional-us-central1").toString()) + InstanceConfigName.of(projectId, "regional-us-east4").toString()) .build(); - + try (Spanner spanner = SpannerOptions.newBuilder() .setProjectId(projectId) @@ -74,4 +74,4 @@ static void createInstance(String projectId, String instanceId) { } } } -//[END spanner_create_instance] \ No newline at end of file +//[END spanner_create_instance] diff --git a/samples/snippets/src/main/java/com/example/spanner/CreateInstanceWithAutoscalingConfigExample.java b/samples/snippets/src/main/java/com/example/spanner/CreateInstanceWithAutoscalingConfigExample.java index dc62dd7a68..0a6e21ea62 100644 --- a/samples/snippets/src/main/java/com/example/spanner/CreateInstanceWithAutoscalingConfigExample.java +++ b/samples/snippets/src/main/java/com/example/spanner/CreateInstanceWithAutoscalingConfigExample.java @@ -45,7 +45,7 @@ static void createInstance(String projectId, String instanceId) { .getService(); InstanceAdminClient instanceAdminClient = spanner.createInstanceAdminClient()) { // Set Instance configuration. - String configId = "regional-us-central1"; + String configId = "regional-us-east4"; String displayName = "Descriptive name"; // Create an autoscaling config. diff --git a/samples/snippets/src/main/java/com/example/spanner/CreateInstanceWithProcessingUnitsExample.java b/samples/snippets/src/main/java/com/example/spanner/CreateInstanceWithProcessingUnitsExample.java index 293c10249c..5113319474 100644 --- a/samples/snippets/src/main/java/com/example/spanner/CreateInstanceWithProcessingUnitsExample.java +++ b/samples/snippets/src/main/java/com/example/spanner/CreateInstanceWithProcessingUnitsExample.java @@ -44,7 +44,7 @@ static void createInstance(String projectId, String instanceId) { InstanceAdminClient instanceAdminClient = spanner.createInstanceAdminClient()) { // Set Instance configuration. - String configId = "regional-us-central1"; + String configId = "regional-us-east4"; // This will create an instance with the processing power of 0.2 nodes. int processingUnits = 500; String displayName = "Descriptive name"; diff --git a/samples/snippets/src/main/java/com/example/spanner/admin/archived/CreateInstanceExample.java b/samples/snippets/src/main/java/com/example/spanner/admin/archived/CreateInstanceExample.java index 15b33ae892..a17784d874 100644 --- a/samples/snippets/src/main/java/com/example/spanner/admin/archived/CreateInstanceExample.java +++ b/samples/snippets/src/main/java/com/example/spanner/admin/archived/CreateInstanceExample.java @@ -42,7 +42,7 @@ static void createInstance(String projectId, String instanceId) { InstanceAdminClient instanceAdminClient = spanner.getInstanceAdminClient(); // Set Instance configuration. - String configId = "regional-us-central1"; + String configId = "regional-us-east4"; int nodeCount = 2; String displayName = "Descriptive name"; diff --git a/samples/snippets/src/main/java/com/example/spanner/admin/archived/CreateInstanceWithAutoscalingConfigExample.java b/samples/snippets/src/main/java/com/example/spanner/admin/archived/CreateInstanceWithAutoscalingConfigExample.java index 3fe60c554b..f8a683865a 100644 --- a/samples/snippets/src/main/java/com/example/spanner/admin/archived/CreateInstanceWithAutoscalingConfigExample.java +++ b/samples/snippets/src/main/java/com/example/spanner/admin/archived/CreateInstanceWithAutoscalingConfigExample.java @@ -44,7 +44,7 @@ static void createInstance(String projectId, String instanceId) { InstanceAdminClient instanceAdminClient = spanner.getInstanceAdminClient(); // Set Instance configuration. - String configId = "regional-us-central1"; + String configId = "regional-us-east4"; // Create an autoscaling config. AutoscalingConfig autoscalingConfig = AutoscalingConfig.newBuilder() diff --git a/samples/snippets/src/main/java/com/example/spanner/admin/archived/CreateInstanceWithProcessingUnitsExample.java b/samples/snippets/src/main/java/com/example/spanner/admin/archived/CreateInstanceWithProcessingUnitsExample.java index f688b4cdbf..95d4f1b673 100644 --- a/samples/snippets/src/main/java/com/example/spanner/admin/archived/CreateInstanceWithProcessingUnitsExample.java +++ b/samples/snippets/src/main/java/com/example/spanner/admin/archived/CreateInstanceWithProcessingUnitsExample.java @@ -42,7 +42,7 @@ static void createInstance(String projectId, String instanceId) { InstanceAdminClient instanceAdminClient = spanner.getInstanceAdminClient(); // Set Instance configuration. - String configId = "regional-us-central1"; + String configId = "regional-us-east4"; // This will create an instance with the processing power of 0.2 nodes. int processingUnits = 500; String displayName = "Descriptive name"; From e336ab81a1d392d56386f9302bf51bf14e385dad Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 6 Aug 2024 21:09:12 +0200 Subject: [PATCH 23/38] deps: update dependency com.google.cloud:google-cloud-trace to v2.47.0 (#3067) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * deps: update dependency com.google.cloud:google-cloud-trace to v2.44.0 * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * deps: bump to 2.47.0 --------- Co-authored-by: Owl Bot Co-authored-by: Knut Olav Løite --- samples/install-without-bom/pom.xml | 2 +- samples/snapshot/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/install-without-bom/pom.xml b/samples/install-without-bom/pom.xml index 0b5d3480ae..ffdab338e5 100644 --- a/samples/install-without-bom/pom.xml +++ b/samples/install-without-bom/pom.xml @@ -23,7 +23,7 @@ 1.8 UTF-8 0.31.1 - 2.41.0 + 2.47.0 3.44.0 diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml index 7f72f2a5ec..ab56c323b1 100644 --- a/samples/snapshot/pom.xml +++ b/samples/snapshot/pom.xml @@ -23,7 +23,7 @@ 1.8 UTF-8 0.31.1 - 2.41.0 + 2.47.0 3.44.0 From 35907c63ae981612ba24dd9605db493b5b864217 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Olav=20L=C3=B8ite?= Date: Tue, 6 Aug 2024 21:32:46 +0200 Subject: [PATCH 24/38] deps: bump sdk-platform-java-config to 3.33.0 (#3243) * deps: bump sdk-platform-java-config to 3.33.0 * chore: add missing tracer method --- .github/workflows/unmanaged_dependency_check.yaml | 2 +- .kokoro/presubmit/graalvm-native-17.cfg | 2 +- .kokoro/presubmit/graalvm-native.cfg | 2 +- google-cloud-spanner-bom/pom.xml | 2 +- .../java/com/google/cloud/spanner/CompositeTracer.java | 7 +++++++ pom.xml | 2 +- 6 files changed, 12 insertions(+), 5 deletions(-) diff --git a/.github/workflows/unmanaged_dependency_check.yaml b/.github/workflows/unmanaged_dependency_check.yaml index eb740eb8ba..2e6ec1a12b 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.32.0 + uses: googleapis/sdk-platform-java/java-shared-dependencies/unmanaged-dependency-check@google-cloud-shared-dependencies/v3.33.0 with: bom-path: google-cloud-spanner-bom/pom.xml diff --git a/.kokoro/presubmit/graalvm-native-17.cfg b/.kokoro/presubmit/graalvm-native-17.cfg index 7d5ab3a25c..7008a72156 100644 --- a/.kokoro/presubmit/graalvm-native-17.cfg +++ b/.kokoro/presubmit/graalvm-native-17.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.32.0" + value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_b:3.33.0" } env_vars: { diff --git a/.kokoro/presubmit/graalvm-native.cfg b/.kokoro/presubmit/graalvm-native.cfg index 519c2e3ce3..931f9bb005 100644 --- a/.kokoro/presubmit/graalvm-native.cfg +++ b/.kokoro/presubmit/graalvm-native.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.32.0" + value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_a:3.33.0" } env_vars: { diff --git a/google-cloud-spanner-bom/pom.xml b/google-cloud-spanner-bom/pom.xml index 8f975232a5..d83678b746 100644 --- a/google-cloud-spanner-bom/pom.xml +++ b/google-cloud-spanner-bom/pom.xml @@ -8,7 +8,7 @@ com.google.cloud sdk-platform-java-config - 3.32.0 + 3.33.0 Google Cloud Spanner BOM diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/CompositeTracer.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/CompositeTracer.java index eed687c416..07d1310e91 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/CompositeTracer.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/CompositeTracer.java @@ -114,6 +114,13 @@ public void attemptFailed(Throwable error, Duration delay) { } } + @Override + public void attemptFailedDuration(Throwable error, java.time.Duration delay) { + for (ApiTracer child : children) { + child.attemptFailedDuration(error, delay); + } + } + @Override public void attemptFailedRetriesExhausted(Throwable error) { for (ApiTracer child : children) { diff --git a/pom.xml b/pom.xml index af104e9200..bf609271ae 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,7 @@ com.google.cloud sdk-platform-java-config - 3.32.0 + 3.33.0 From 52f8684b1ab1fa6e040067742186dcd5b522e759 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Olav=20L=C3=B8ite?= Date: Wed, 7 Aug 2024 12:51:41 +0200 Subject: [PATCH 25/38] test: speed up ITDmlReturningTest (#3248) The initialization code for ITDmlReturningTest was borked and initialized the database over and over again for each test method. This pushes Spanner into throttling the DDL requests, which again makes both this and other integration tests slow. Updates #3247 --- .../connection/it/ITDmlReturningTest.java | 71 ++++++++----------- 1 file changed, 30 insertions(+), 41 deletions(-) diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITDmlReturningTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITDmlReturningTest.java index 5e5ca80040..83f9beb7cf 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITDmlReturningTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITDmlReturningTest.java @@ -22,12 +22,13 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeFalse; import com.google.cloud.spanner.AsyncResultSet; import com.google.cloud.spanner.AsyncResultSet.CallbackResponse; +import com.google.cloud.spanner.DatabaseClient; import com.google.cloud.spanner.Dialect; import com.google.cloud.spanner.ErrorCode; +import com.google.cloud.spanner.KeySet; import com.google.cloud.spanner.Mutation; import com.google.cloud.spanner.ParallelIntegrationTest; import com.google.cloud.spanner.ResultSet; @@ -39,15 +40,15 @@ import com.google.cloud.spanner.connection.StatementResult; import com.google.cloud.spanner.connection.StatementResult.ResultType; import com.google.cloud.spanner.connection.TransactionMode; -import com.google.cloud.spanner.testing.EmulatorSpannerHelper; +import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.HashMap; +import java.util.HashSet; import java.util.List; -import java.util.Map; +import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executors; import org.junit.Before; @@ -81,12 +82,7 @@ public class ITDmlReturningTest extends ITAbstractSpannerTest { + " SingerId BIGINT PRIMARY KEY," + " FirstName character varying(1024)," + " LastName character varying(1024))"); - private final Map IS_INITIALIZED = new HashMap<>(); - - public ITDmlReturningTest() { - IS_INITIALIZED.put(Dialect.GOOGLE_STANDARD_SQL, false); - IS_INITIALIZED.put(Dialect.POSTGRESQL, false); - } + private static final Set IS_INITIALIZED = new HashSet<>(); @Parameter public Dialect dialect; @@ -96,41 +92,34 @@ public static Object[] data() { } private boolean checkAndSetInitialized() { - if ((dialect == Dialect.GOOGLE_STANDARD_SQL) && !IS_INITIALIZED.get(dialect)) { - IS_INITIALIZED.put(dialect, true); - return true; - } - if ((dialect == Dialect.POSTGRESQL) && !IS_INITIALIZED.get(dialect)) { - IS_INITIALIZED.put(dialect, true); - return true; - } - return false; + return !IS_INITIALIZED.add(dialect); } @Before public void setupTable() { - assumeFalse( - "DML Returning is not supported in the emulator", EmulatorSpannerHelper.isUsingEmulator()); - if (checkAndSetInitialized()) { + if (!checkAndSetInitialized()) { database = env.getTestHelper() .createTestDatabase(dialect, Collections.singleton(DDL_MAP.get(dialect))); - List firstNames = Arrays.asList("ABC", "ABC", "DEF", "PQR", "ABC"); - List lastNames = Arrays.asList("XYZ", "DEF", "XYZ", "ABC", "GHI"); - List mutations = new ArrayList<>(); - for (int id = 1; id <= 5; id++) { - mutations.add( - Mutation.newInsertBuilder("SINGERS") - .set("SINGERID") - .to(id) - .set("FIRSTNAME") - .to(firstNames.get(id - 1)) - .set("LASTNAME") - .to(lastNames.get(id - 1)) - .build()); - } - env.getTestHelper().getDatabaseClient(database).write(mutations); } + DatabaseClient client = env.getTestHelper().getDatabaseClient(database); + client.write(ImmutableList.of(Mutation.delete("SINGERS", KeySet.all()))); + + List firstNames = Arrays.asList("ABC", "ABC", "DEF", "PQR", "ABC"); + List lastNames = Arrays.asList("XYZ", "DEF", "XYZ", "ABC", "GHI"); + List mutations = new ArrayList<>(); + for (int id = 1; id <= 5; id++) { + mutations.add( + Mutation.newInsertBuilder("SINGERS") + .set("SINGERID") + .to(id) + .set("FIRSTNAME") + .to(firstNames.get(id - 1)) + .set("LASTNAME") + .to(lastNames.get(id - 1)) + .build()); + } + env.getTestHelper().getDatabaseClient(database).write(mutations); } @Test @@ -211,9 +200,9 @@ public void testDmlReturningExecuteUpdateAsync() { public void testDmlReturningExecuteBatchUpdate() { try (Connection connection = createConnection()) { connection.setAutocommit(false); - final Statement UPDATE_STMT = UPDATE_RETURNING_MAP.get(dialect); + final Statement updateStmt = Preconditions.checkNotNull(UPDATE_RETURNING_MAP.get(dialect)); long[] counts = - connection.executeBatchUpdate(ImmutableList.of(UPDATE_STMT, UPDATE_STMT, UPDATE_STMT)); + connection.executeBatchUpdate(ImmutableList.of(updateStmt, updateStmt, updateStmt)); assertArrayEquals(counts, new long[] {3, 3, 3}); } } @@ -222,10 +211,10 @@ public void testDmlReturningExecuteBatchUpdate() { public void testDmlReturningExecuteBatchUpdateAsync() { try (Connection connection = createConnection()) { connection.setAutocommit(false); - final Statement UPDATE_STMT = UPDATE_RETURNING_MAP.get(dialect); + final Statement updateStmt = Preconditions.checkNotNull(UPDATE_RETURNING_MAP.get(dialect)); long[] counts = connection - .executeBatchUpdateAsync(ImmutableList.of(UPDATE_STMT, UPDATE_STMT, UPDATE_STMT)) + .executeBatchUpdateAsync(ImmutableList.of(updateStmt, updateStmt, updateStmt)) .get(); assertArrayEquals(counts, new long[] {3, 3, 3}); } catch (ExecutionException | InterruptedException e) { From 92c17c7c4817297f18c6eaccd54b202c063f9729 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Olav=20L=C3=B8ite?= Date: Wed, 7 Aug 2024 13:50:40 +0200 Subject: [PATCH 26/38] build: increase parallelism for integration tests (#3249) * build: increase parallelism for integration tests * fix: BulkConnectionTest must run serially --- google-cloud-spanner/pom.xml | 2 +- .../cloud/spanner/connection/it/ITBulkConnectionTest.java | 4 ++-- .../cloud/spanner/connection/it/ITQueryOptionsTest.java | 6 ++++++ .../java/com/google/cloud/spanner/it/ITAsyncAPITest.java | 4 ++-- .../com/google/cloud/spanner/it/ITAsyncExamplesTest.java | 4 ++-- 5 files changed, 13 insertions(+), 7 deletions(-) diff --git a/google-cloud-spanner/pom.xml b/google-cloud-spanner/pom.xml index 8a79e70362..7ea8a1cb5e 100644 --- a/google-cloud-spanner/pom.xml +++ b/google-cloud-spanner/pom.xml @@ -107,7 +107,7 @@ com.google.cloud.spanner.ParallelIntegrationTest - 8 + 12 true com.google.cloud.spanner.ParallelIntegrationTest diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITBulkConnectionTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITBulkConnectionTest.java index 9cc46e6ee1..42358a647a 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITBulkConnectionTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITBulkConnectionTest.java @@ -36,8 +36,8 @@ /** * Test opening multiple generic (not JDBC) Spanner connections. This test should not be run in - * parallel with other tests, as it tries to close all active connections, and should not try to - * close connections of other integration tests. + * parallel with other tests in the same JVM, as it tries to close all active connections, and + * should not try to close connections of other integration tests. */ @Category(SerialIntegrationTest.class) @RunWith(JUnit4.class) diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITQueryOptionsTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITQueryOptionsTest.java index 09f4ada43a..62eba4f431 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITQueryOptionsTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITQueryOptionsTest.java @@ -16,12 +16,18 @@ package com.google.cloud.spanner.connection.it; +import com.google.cloud.spanner.ParallelIntegrationTest; import com.google.cloud.spanner.connection.ITAbstractSpannerTest; import com.google.cloud.spanner.connection.SqlScriptVerifier; import com.google.cloud.spanner.connection.SqlScriptVerifier.SpannerGenericConnection; import org.junit.Before; import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +@Category(ParallelIntegrationTest.class) +@RunWith(JUnit4.class) public class ITQueryOptionsTest extends ITAbstractSpannerTest { private static final String TEST_QUERY_OPTIONS = "ITSqlScriptTest_TestQueryOptions.sql"; diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITAsyncAPITest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITAsyncAPITest.java index ebd3ab4883..1e408fadf3 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITAsyncAPITest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITAsyncAPITest.java @@ -42,7 +42,7 @@ import com.google.cloud.spanner.KeySet; import com.google.cloud.spanner.Mutation; import com.google.cloud.spanner.Options; -import com.google.cloud.spanner.SerialIntegrationTest; +import com.google.cloud.spanner.ParallelIntegrationTest; import com.google.cloud.spanner.SpannerException; import com.google.cloud.spanner.Statement; import com.google.cloud.spanner.Struct; @@ -68,7 +68,7 @@ import org.junit.runners.JUnit4; /** Integration tests for asynchronous APIs. */ -@Category(SerialIntegrationTest.class) +@Category(ParallelIntegrationTest.class) @RunWith(JUnit4.class) public class ITAsyncAPITest { @ClassRule public static IntegrationTestEnv env = new IntegrationTestEnv(); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITAsyncExamplesTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITAsyncExamplesTest.java index 87f26da904..dc5abd77af 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITAsyncExamplesTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITAsyncExamplesTest.java @@ -33,8 +33,8 @@ import com.google.cloud.spanner.Key; import com.google.cloud.spanner.KeySet; import com.google.cloud.spanner.Mutation; +import com.google.cloud.spanner.ParallelIntegrationTest; import com.google.cloud.spanner.ReadOnlyTransaction; -import com.google.cloud.spanner.SerialIntegrationTest; import com.google.cloud.spanner.SpannerException; import com.google.cloud.spanner.Statement; import com.google.cloud.spanner.Struct; @@ -59,7 +59,7 @@ import org.junit.runners.JUnit4; /** Integration tests for asynchronous APIs. */ -@Category(SerialIntegrationTest.class) +@Category(ParallelIntegrationTest.class) @RunWith(JUnit4.class) public class ITAsyncExamplesTest { @ClassRule public static IntegrationTestEnv env = new IntegrationTestEnv(); From d515fb757f535bbdc500a998bb745d15f4977ec7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Olav=20L=C3=B8ite?= Date: Wed, 7 Aug 2024 13:50:53 +0200 Subject: [PATCH 27/38] chore: improve test execution speed (#3245) * chore: improve test execution speed Improves the unit test execution speed from around 2m15s to around 60s. * fix: remove print statement --- .../cloud/spanner/DatabaseClientImplTest.java | 5 +- .../google/cloud/spanner/SessionPoolTest.java | 22 ++- .../cloud/spanner/spi/v1/GfeLatencyTest.java | 163 ++++++++---------- 3 files changed, 87 insertions(+), 103 deletions(-) diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseClientImplTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseClientImplTest.java index 3dacd43a55..62a10c0adb 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseClientImplTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseClientImplTest.java @@ -3859,7 +3859,8 @@ public void testBatchCreateSessionsFailure_shouldNotPropagateToCloseMethod() { try { // Simulate session creation failures on the backend. mockSpanner.setBatchCreateSessionsExecutionTime( - SimulatedExecutionTime.ofStickyException(Status.RESOURCE_EXHAUSTED.asRuntimeException())); + SimulatedExecutionTime.ofStickyException( + Status.FAILED_PRECONDITION.asRuntimeException())); DatabaseClient client = spannerWithEmptySessionPool.getDatabaseClient( DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); @@ -3867,7 +3868,7 @@ public void testBatchCreateSessionsFailure_shouldNotPropagateToCloseMethod() { // non-blocking, and any exceptions will be delayed until actual query execution. try (ResultSet rs = client.singleUse().executeQuery(SELECT1)) { SpannerException e = assertThrows(SpannerException.class, rs::next); - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.RESOURCE_EXHAUSTED); + assertThat(e.getErrorCode()).isEqualTo(ErrorCode.FAILED_PRECONDITION); } } finally { mockSpanner.setBatchCreateSessionsExecutionTime(SimulatedExecutionTime.none()); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolTest.java index 564e2b97aa..58b0280cf0 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolTest.java @@ -74,6 +74,7 @@ import com.google.cloud.spanner.spi.v1.SpannerRpc; import com.google.cloud.spanner.spi.v1.SpannerRpc.ResultStreamConsumer; import com.google.cloud.spanner.v1.stub.SpannerStubSettings; +import com.google.common.base.Stopwatch; import com.google.common.collect.Lists; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.Uninterruptibles; @@ -2022,14 +2023,16 @@ public void testOpenCensusMetricsDisable() { public void testOpenTelemetrySessionMetrics() throws Exception { SpannerOptions.resetActiveTracingFramework(); SpannerOptions.enableOpenTelemetryMetrics(); - // Create a session pool with max 2 session and a low timeout for waiting for a session. + // Create a session pool with max 3 session and a low timeout for waiting for a session. if (minSessions == 1) { options = SessionPoolOptions.newBuilder() .setMinSessions(1) .setMaxSessions(3) - .setMaxIdleSessions(0) - .setInitialWaitForSessionTimeoutMillis(50L) + // This must be set to null for the setInitialWaitForSessionTimeoutMillis call to have + // any effect. + .setAcquireSessionTimeout(null) + .setInitialWaitForSessionTimeoutMillis(1L) .build(); FakeClock clock = new FakeClock(); clock.currentTimeMillis.set(System.currentTimeMillis()); @@ -2080,26 +2083,29 @@ public void testOpenTelemetrySessionMetrics() throws Exception { Future fut = executor.submit( () -> { + PooledSessionFuture session = pool.getSession(); latch.countDown(); - Session session = pool.getSession(); + session.get(); session.close(); return null; }); // Wait until the background thread is actually waiting for a session. latch.await(); // Wait until the request has timed out. - int waitCount = 0; - while (pool.getNumWaiterTimeouts() == 0L && waitCount < 1000) { - Thread.sleep(5L); - waitCount++; + Stopwatch watch = Stopwatch.createStarted(); + while (pool.getNumWaiterTimeouts() == 0L && watch.elapsed(TimeUnit.MILLISECONDS) < 100) { + Thread.yield(); } + assertTrue(pool.getNumWaiterTimeouts() > 0); // Return the checked out session to the pool so the async request will get a session and // finish. session2.close(); // Verify that the async request also succeeds. fut.get(10L, TimeUnit.SECONDS); executor.shutdown(); + assertTrue(executor.awaitTermination(10L, TimeUnit.SECONDS)); + inMemoryMetricReader.forceFlush(); metricDataCollection = inMemoryMetricReader.collectAllMetrics(); // Max Allowed sessions should be 3 diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/spi/v1/GfeLatencyTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/spi/v1/GfeLatencyTest.java index 9bb09aace7..908a4ad557 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/spi/v1/GfeLatencyTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/spi/v1/GfeLatencyTest.java @@ -17,6 +17,7 @@ package com.google.cloud.spanner.spi.v1; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import com.google.auth.oauth2.AccessToken; import com.google.auth.oauth2.OAuth2Credentials; @@ -27,6 +28,8 @@ import com.google.cloud.spanner.Spanner; import com.google.cloud.spanner.SpannerOptions; import com.google.cloud.spanner.Statement; +import com.google.common.base.MoreObjects; +import com.google.common.base.Preconditions; import com.google.protobuf.ListValue; import com.google.spanner.v1.ResultSetMetadata; import com.google.spanner.v1.StructType; @@ -47,7 +50,6 @@ import io.opencensus.tags.TagValue; import java.io.IOException; import java.net.InetSocketAddress; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Random; @@ -80,26 +82,22 @@ public class GfeLatencyTest { private static MockSpannerServiceImpl mockSpanner; private static Server server; - private static InetSocketAddress address; private static Spanner spanner; private static DatabaseClient databaseClient; - private static final Map optionsMap = new HashMap<>(); - private static MockSpannerServiceImpl mockSpannerNoHeader; private static Server serverNoHeader; - private static InetSocketAddress addressNoHeader; private static Spanner spannerNoHeader; private static DatabaseClient databaseClientNoHeader; - private static String instanceId = "fake-instance"; - private static String databaseId = "fake-database"; - private static String projectId = "fake-project"; + private static final String INSTANCE_ID = "fake-instance"; + private static final String DATABASE_ID = "fake-database"; + private static final String PROJECT_ID = "fake-project"; - private static final long WAIT_FOR_METRICS_TIME_MS = 1_000; - private static final int MAXIMUM_RETRIES = 5; + private static final int MAXIMUM_RETRIES = 50000; - private static AtomicInteger fakeServerTiming = new AtomicInteger(new Random().nextInt(1000) + 1); + private static final AtomicInteger FAKE_SERVER_TIMING = + new AtomicInteger(new Random().nextInt(1000) + 1); private static final Statement SELECT1AND2 = Statement.of("SELECT 1 AS COL1 UNION ALL SELECT 2 AS COL1"); @@ -135,6 +133,7 @@ public class GfeLatencyTest { @BeforeClass public static void startServer() throws IOException { + //noinspection deprecation SpannerRpcViews.registerGfeLatencyAndHeaderMissingCountViews(); mockSpanner = new MockSpannerServiceImpl(); @@ -143,7 +142,7 @@ public static void startServer() throws IOException { MockSpannerServiceImpl.StatementResult.query(SELECT1AND2, SELECT1_RESULTSET)); mockSpanner.putStatementResult( MockSpannerServiceImpl.StatementResult.update(UPDATE_FOO_STATEMENT, 1L)); - address = new InetSocketAddress("localhost", 0); + InetSocketAddress address = new InetSocketAddress("localhost", 0); server = NettyServerBuilder.forAddress(address) .addService(mockSpanner) @@ -161,7 +160,7 @@ public ServerCall.Listener interceptCall( public void sendHeaders(Metadata headers) { headers.put( Metadata.Key.of("server-timing", Metadata.ASCII_STRING_MARSHALLER), - String.format("gfet4t7; dur=%d", fakeServerTiming.get())); + String.format("gfet4t7; dur=%d", FAKE_SERVER_TIMING.get())); super.sendHeaders(headers); } }, @@ -170,9 +169,8 @@ public void sendHeaders(Metadata headers) { }) .build() .start(); - optionsMap.put(SpannerRpc.Option.CHANNEL_HINT, 1L); spanner = createSpannerOptions(address, server).getService(); - databaseClient = spanner.getDatabaseClient(DatabaseId.of(projectId, instanceId, databaseId)); + databaseClient = spanner.getDatabaseClient(DatabaseId.of(PROJECT_ID, INSTANCE_ID, DATABASE_ID)); mockSpannerNoHeader = new MockSpannerServiceImpl(); mockSpannerNoHeader.setAbortProbability(0.0D); @@ -180,7 +178,7 @@ public void sendHeaders(Metadata headers) { MockSpannerServiceImpl.StatementResult.query(SELECT1AND2, SELECT1_RESULTSET)); mockSpannerNoHeader.putStatementResult( MockSpannerServiceImpl.StatementResult.update(UPDATE_FOO_STATEMENT, 1L)); - addressNoHeader = new InetSocketAddress("localhost", 0); + InetSocketAddress addressNoHeader = new InetSocketAddress("localhost", 0); serverNoHeader = NettyServerBuilder.forAddress(addressNoHeader) .addService(mockSpannerNoHeader) @@ -188,7 +186,7 @@ public void sendHeaders(Metadata headers) { .start(); spannerNoHeader = createSpannerOptions(addressNoHeader, serverNoHeader).getService(); databaseClientNoHeader = - spannerNoHeader.getDatabaseClient(DatabaseId.of(projectId, instanceId, databaseId)); + spannerNoHeader.getDatabaseClient(DatabaseId.of(PROJECT_ID, INSTANCE_ID, DATABASE_ID)); } @AfterClass @@ -221,12 +219,9 @@ public void testGfeLatencyExecuteStreamingSql() throws InterruptedException { long latency = getMetric( SpannerRpcViews.SPANNER_GFE_LATENCY_VIEW, - projectId, - instanceId, - databaseId, "google.spanner.v1.Spanner/ExecuteStreamingSql", false); - assertEquals(fakeServerTiming.get(), latency); + assertEquals(FAKE_SERVER_TIMING.get(), latency); } @Test @@ -238,12 +233,9 @@ public void testGfeLatencyExecuteSql() throws InterruptedException { long latency = getMetric( SpannerRpcViews.SPANNER_GFE_LATENCY_VIEW, - projectId, - instanceId, - databaseId, "google.spanner.v1.Spanner/ExecuteSql", false); - assertEquals(fakeServerTiming.get(), latency); + assertEquals(FAKE_SERVER_TIMING.get(), latency); } @Test @@ -254,9 +246,6 @@ public void testGfeMissingHeaderCountExecuteStreamingSql() throws InterruptedExc long count = getMetric( SpannerRpcViews.SPANNER_GFE_HEADER_MISSING_COUNT_VIEW, - projectId, - instanceId, - databaseId, "google.spanner.v1.Spanner/ExecuteStreamingSql", false); assertEquals(0, count); @@ -267,9 +256,6 @@ public void testGfeMissingHeaderCountExecuteStreamingSql() throws InterruptedExc long count1 = getMetric( SpannerRpcViews.SPANNER_GFE_HEADER_MISSING_COUNT_VIEW, - projectId, - instanceId, - databaseId, "google.spanner.v1.Spanner/ExecuteStreamingSql", true); assertEquals(1, count1); @@ -283,9 +269,6 @@ public void testGfeMissingHeaderExecuteSql() throws InterruptedException { long count = getMetric( SpannerRpcViews.SPANNER_GFE_HEADER_MISSING_COUNT_VIEW, - projectId, - instanceId, - databaseId, "google.spanner.v1.Spanner/ExecuteSql", false); assertEquals(0, count); @@ -296,9 +279,6 @@ public void testGfeMissingHeaderExecuteSql() throws InterruptedException { long count1 = getMetric( SpannerRpcViews.SPANNER_GFE_HEADER_MISSING_COUNT_VIEW, - projectId, - instanceId, - databaseId, "google.spanner.v1.Spanner/ExecuteSql", true); assertEquals(1, count1); @@ -321,78 +301,75 @@ private static SpannerOptions createSpannerOptions(InetSocketAddress address, Se } private long getAggregationValueAsLong(AggregationData aggregationData) { - return aggregationData.match( - new io.opencensus.common.Function() { - @Override - public Long apply(AggregationData.SumDataDouble arg) { - return (long) arg.getSum(); - } - }, - new io.opencensus.common.Function() { - @Override - public Long apply(AggregationData.SumDataLong arg) { - return arg.getSum(); - } - }, - new io.opencensus.common.Function() { - @Override - public Long apply(AggregationData.CountData arg) { - return arg.getCount(); - } - }, - new io.opencensus.common.Function() { - @Override - public Long apply(AggregationData.DistributionData arg) { - return (long) arg.getMean(); - } - }, - new io.opencensus.common.Function() { - @Override - public Long apply(AggregationData.LastValueDataDouble arg) { - return (long) arg.getLastValue(); - } - }, - new io.opencensus.common.Function() { - @Override - public Long apply(AggregationData.LastValueDataLong arg) { - return arg.getLastValue(); - } - }, - new io.opencensus.common.Function() { - @Override - public Long apply(AggregationData arg) { - throw new UnsupportedOperationException(); - } - }); + return MoreObjects.firstNonNull( + aggregationData.match( + new io.opencensus.common.Function() { + @Override + public Long apply(AggregationData.SumDataDouble arg) { + return (long) Preconditions.checkNotNull(arg).getSum(); + } + }, + new io.opencensus.common.Function() { + @Override + public Long apply(AggregationData.SumDataLong arg) { + return Preconditions.checkNotNull(arg).getSum(); + } + }, + new io.opencensus.common.Function() { + @Override + public Long apply(AggregationData.CountData arg) { + return Preconditions.checkNotNull(arg).getCount(); + } + }, + new io.opencensus.common.Function() { + @Override + public Long apply(AggregationData.DistributionData arg) { + return (long) Preconditions.checkNotNull(arg).getMean(); + } + }, + new io.opencensus.common.Function() { + @Override + public Long apply(AggregationData.LastValueDataDouble arg) { + return (long) Preconditions.checkNotNull(arg).getLastValue(); + } + }, + new io.opencensus.common.Function() { + @Override + public Long apply(AggregationData.LastValueDataLong arg) { + return Preconditions.checkNotNull(arg).getLastValue(); + } + }, + new io.opencensus.common.Function() { + @Override + public Long apply(AggregationData arg) { + throw new UnsupportedOperationException(); + } + }), + -1L); } - private long getMetric( - View view, - String projectId, - String instanceId, - String databaseId, - String method, - boolean withOverride) - throws InterruptedException { + private long getMetric(View view, String method, boolean withOverride) { List tagValues = new java.util.ArrayList<>(); for (TagKey column : view.getColumns()) { if (column == SpannerRpcViews.INSTANCE_ID) { - tagValues.add(TagValue.create(instanceId)); + tagValues.add(TagValue.create(INSTANCE_ID)); } else if (column == SpannerRpcViews.DATABASE_ID) { - tagValues.add(TagValue.create(databaseId)); + tagValues.add(TagValue.create(DATABASE_ID)); } else if (column == SpannerRpcViews.METHOD) { tagValues.add(TagValue.create(method)); } else if (column == SpannerRpcViews.PROJECT_ID) { - tagValues.add(TagValue.create(projectId)); + tagValues.add(TagValue.create(PROJECT_ID)); } } for (int i = 0; i < MAXIMUM_RETRIES; i++) { - Thread.sleep(WAIT_FOR_METRICS_TIME_MS); + Thread.yield(); ViewData viewData = SpannerRpcViews.viewManager.getView(view.getName()); + assertNotNull(viewData); if (viewData.getAggregationMap() != null) { Map, AggregationData> aggregationMap = viewData.getAggregationMap(); AggregationData aggregationData = aggregationMap.get(tagValues); - if (withOverride && getAggregationValueAsLong(aggregationData) == 0) { + if (aggregationData == null + || withOverride && getAggregationValueAsLong(aggregationData) == 0) { continue; } return getAggregationValueAsLong(aggregationData); From d1d566b096915a537e0978715c81bfca00e34ceb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Olav=20L=C3=B8ite?= Date: Wed, 7 Aug 2024 14:34:00 +0200 Subject: [PATCH 28/38] deps: update dependencies to latest (#3250) --- benchmarks/pom.xml | 12 ++++++------ google-cloud-spanner/pom.xml | 4 ++-- pom.xml | 2 +- samples/install-without-bom/pom.xml | 4 ++-- samples/native-image/pom.xml | 4 ++-- samples/snapshot/pom.xml | 4 ++-- samples/snippets/pom.xml | 2 +- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index 773e2116a0..debcaa11e8 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -33,8 +33,8 @@ 1.8 UTF-8 UTF-8 - 2.9.1 - 1.39.0 + 2.10.0 + 1.40.0 @@ -49,12 +49,12 @@ com.google.cloud.opentelemetry exporter-trace - 0.29.0 + 0.31.0 com.google.cloud.opentelemetry exporter-metrics - 0.29.0 + 0.31.0 @@ -85,7 +85,7 @@ io.opentelemetry opentelemetry-bom - 1.39.0 + 1.40.0 pom import @@ -133,7 +133,7 @@ org.codehaus.mojo exec-maven-plugin - 3.3.0 + 3.4.0 com.google.cloud.spanner.benchmark.LatencyBenchmark false diff --git a/google-cloud-spanner/pom.xml b/google-cloud-spanner/pom.xml index 7ea8a1cb5e..0002667f98 100644 --- a/google-cloud-spanner/pom.xml +++ b/google-cloud-spanner/pom.xml @@ -266,12 +266,12 @@ com.google.cloud google-cloud-monitoring - 3.38.0 + 3.48.0 com.google.api.grpc proto-google-cloud-monitoring-v3 - 3.38.0 + 3.48.0 com.google.auth diff --git a/pom.xml b/pom.xml index bf609271ae..8897047df7 100644 --- a/pom.xml +++ b/pom.xml @@ -121,7 +121,7 @@ com.google.truth truth - 1.4.2 + 1.4.4 test diff --git a/samples/install-without-bom/pom.xml b/samples/install-without-bom/pom.xml index ffdab338e5..56b1c708c8 100644 --- a/samples/install-without-bom/pom.xml +++ b/samples/install-without-bom/pom.xml @@ -24,7 +24,7 @@ UTF-8 0.31.1 2.47.0 - 3.44.0 + 3.48.0 @@ -100,7 +100,7 @@ com.google.truth truth - 1.4.2 + 1.4.4 test diff --git a/samples/native-image/pom.xml b/samples/native-image/pom.xml index 4eae18226c..b34fc04848 100644 --- a/samples/native-image/pom.xml +++ b/samples/native-image/pom.xml @@ -51,7 +51,7 @@ com.google.truth truth - 1.4.2 + 1.4.4 test @@ -104,7 +104,7 @@ org.junit.vintage junit-vintage-engine - 5.10.2 + 5.10.3 test diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml index ab56c323b1..acf50d15e8 100644 --- a/samples/snapshot/pom.xml +++ b/samples/snapshot/pom.xml @@ -24,7 +24,7 @@ UTF-8 0.31.1 2.47.0 - 3.44.0 + 3.48.0 @@ -99,7 +99,7 @@ com.google.truth truth - 1.4.2 + 1.4.4 test diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml index b0575d5ea9..c96c572d50 100644 --- a/samples/snippets/pom.xml +++ b/samples/snippets/pom.xml @@ -111,7 +111,7 @@ com.google.truth truth - 1.4.2 + 1.4.4 test From bcaaf2c083cf9164606cb696f5764de29b7c7985 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Wed, 7 Aug 2024 15:34:13 +0200 Subject: [PATCH 29/38] chore(main): release 6.72.0 (#3199) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- CHANGELOG.md | 31 +++++++++++++++++++ benchmarks/pom.xml | 2 +- google-cloud-spanner-bom/pom.xml | 18 +++++------ google-cloud-spanner-executor/pom.xml | 4 +-- google-cloud-spanner/pom.xml | 4 +-- .../pom.xml | 4 +-- .../pom.xml | 4 +-- grpc-google-cloud-spanner-executor-v1/pom.xml | 4 +-- grpc-google-cloud-spanner-v1/pom.xml | 4 +-- pom.xml | 20 ++++++------ .../pom.xml | 4 +-- .../pom.xml | 4 +-- .../pom.xml | 4 +-- proto-google-cloud-spanner-v1/pom.xml | 4 +-- samples/snapshot/pom.xml | 2 +- versions.txt | 20 ++++++------ 16 files changed, 82 insertions(+), 51 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e996cccc5a..fc0757052a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,36 @@ # Changelog +## [6.72.0](https://github.com/googleapis/java-spanner/compare/v6.71.0...v6.72.0) (2024-08-07) + + +### Features + +* Add `RESOURCE_EXHAUSTED` to the list of retryable error codes ([e859b29](https://github.com/googleapis/java-spanner/commit/e859b29ccf4e68b1ab62cffdd4cf197011ba9878)) +* Add field order_by in spanner.proto ([e859b29](https://github.com/googleapis/java-spanner/commit/e859b29ccf4e68b1ab62cffdd4cf197011ba9878)) +* Add QueryCancellationAction message in executor protos ([e859b29](https://github.com/googleapis/java-spanner/commit/e859b29ccf4e68b1ab62cffdd4cf197011ba9878)) +* Add SessionPoolOptions, SpannerOptions protos in executor protos ([e859b29](https://github.com/googleapis/java-spanner/commit/e859b29ccf4e68b1ab62cffdd4cf197011ba9878)) +* Add support for multi region encryption config ([e859b29](https://github.com/googleapis/java-spanner/commit/e859b29ccf4e68b1ab62cffdd4cf197011ba9878)) +* Enable hermetic library generation ([#3129](https://github.com/googleapis/java-spanner/issues/3129)) ([94b2a86](https://github.com/googleapis/java-spanner/commit/94b2a8610ac02d2b4212c421f03b4e9561ec9949)) +* **spanner:** Add samples for instance partitions ([#3221](https://github.com/googleapis/java-spanner/issues/3221)) ([bc48bf2](https://github.com/googleapis/java-spanner/commit/bc48bf212e37441221b3b6c8742b07ff601f6c41)) +* **spanner:** Add support for Cloud Spanner Scheduled Backups ([e859b29](https://github.com/googleapis/java-spanner/commit/e859b29ccf4e68b1ab62cffdd4cf197011ba9878)) +* **spanner:** Adding `EXPECTED_FULFILLMENT_PERIOD` to the indicate instance creation times (with `FULFILLMENT_PERIOD_NORMAL` or `FULFILLMENT_PERIOD_EXTENDED` ENUM) with the extended instance creation time triggered by On-Demand Capacity Feature ([e859b29](https://github.com/googleapis/java-spanner/commit/e859b29ccf4e68b1ab62cffdd4cf197011ba9878)) +* **spanner:** Set manual affinity incase of gRPC-GCP extenstion ([#3215](https://github.com/googleapis/java-spanner/issues/3215)) ([86b306a](https://github.com/googleapis/java-spanner/commit/86b306a4189483a5fd2746052bed817443630567)) +* Support Read RPC OrderBy ([#3180](https://github.com/googleapis/java-spanner/issues/3180)) ([735bca5](https://github.com/googleapis/java-spanner/commit/735bca523e4ea53a24929fb2c27d282c41350e91)) + + +### Bug Fixes + +* Make sure commitAsync always finishes ([#3216](https://github.com/googleapis/java-spanner/issues/3216)) ([440c88b](https://github.com/googleapis/java-spanner/commit/440c88bd67e1c9d08445fe26b01bf243f7fd1ca4)) +* SessionPoolOptions.Builder#toBuilder() skipped useMultiplexedSessions ([#3197](https://github.com/googleapis/java-spanner/issues/3197)) ([027f92c](https://github.com/googleapis/java-spanner/commit/027f92cf32fee8217d2075db61fe0be58d43a40d)) + + +### Dependencies + +* Bump sdk-platform-java-config to 3.33.0 ([#3243](https://github.com/googleapis/java-spanner/issues/3243)) ([35907c6](https://github.com/googleapis/java-spanner/commit/35907c63ae981612ba24dd9605db493b5b864217)) +* Update dependencies to latest ([#3250](https://github.com/googleapis/java-spanner/issues/3250)) ([d1d566b](https://github.com/googleapis/java-spanner/commit/d1d566b096915a537e0978715c81bfca00e34ceb)) +* Update dependency com.google.auto.value:auto-value-annotations to v1.11.0 ([#3191](https://github.com/googleapis/java-spanner/issues/3191)) ([065cd48](https://github.com/googleapis/java-spanner/commit/065cd489964aaee42fffe1e71327906bde907205)) +* Update dependency com.google.cloud:google-cloud-trace to v2.47.0 ([#3067](https://github.com/googleapis/java-spanner/issues/3067)) ([e336ab8](https://github.com/googleapis/java-spanner/commit/e336ab81a1d392d56386f9302bf51bf14e385dad)) + ## [6.71.0](https://github.com/googleapis/java-spanner/compare/v6.70.0...v6.71.0) (2024-07-03) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index debcaa11e8..ae700bd337 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -24,7 +24,7 @@ com.google.cloud google-cloud-spanner-parent - 6.71.1-SNAPSHOT + 6.72.0 diff --git a/google-cloud-spanner-bom/pom.xml b/google-cloud-spanner-bom/pom.xml index d83678b746..fa9e6207a2 100644 --- a/google-cloud-spanner-bom/pom.xml +++ b/google-cloud-spanner-bom/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.cloud google-cloud-spanner-bom - 6.71.1-SNAPSHOT + 6.72.0 pom com.google.cloud @@ -53,43 +53,43 @@ com.google.cloud google-cloud-spanner - 6.71.1-SNAPSHOT + 6.72.0 com.google.cloud google-cloud-spanner test-jar - 6.71.1-SNAPSHOT + 6.72.0 com.google.api.grpc grpc-google-cloud-spanner-v1 - 6.71.1-SNAPSHOT + 6.72.0 com.google.api.grpc grpc-google-cloud-spanner-admin-instance-v1 - 6.71.1-SNAPSHOT + 6.72.0 com.google.api.grpc grpc-google-cloud-spanner-admin-database-v1 - 6.71.1-SNAPSHOT + 6.72.0 com.google.api.grpc proto-google-cloud-spanner-admin-instance-v1 - 6.71.1-SNAPSHOT + 6.72.0 com.google.api.grpc proto-google-cloud-spanner-v1 - 6.71.1-SNAPSHOT + 6.72.0 com.google.api.grpc proto-google-cloud-spanner-admin-database-v1 - 6.71.1-SNAPSHOT + 6.72.0 diff --git a/google-cloud-spanner-executor/pom.xml b/google-cloud-spanner-executor/pom.xml index dc4f6d81ac..3a99cd0062 100644 --- a/google-cloud-spanner-executor/pom.xml +++ b/google-cloud-spanner-executor/pom.xml @@ -5,14 +5,14 @@ 4.0.0 com.google.cloud google-cloud-spanner-executor - 6.71.1-SNAPSHOT + 6.72.0 jar Google Cloud Spanner Executor com.google.cloud google-cloud-spanner-parent - 6.71.1-SNAPSHOT + 6.72.0 diff --git a/google-cloud-spanner/pom.xml b/google-cloud-spanner/pom.xml index 0002667f98..5f42b91fd7 100644 --- a/google-cloud-spanner/pom.xml +++ b/google-cloud-spanner/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.cloud google-cloud-spanner - 6.71.1-SNAPSHOT + 6.72.0 jar Google Cloud Spanner https://github.com/googleapis/java-spanner @@ -11,7 +11,7 @@ com.google.cloud google-cloud-spanner-parent - 6.71.1-SNAPSHOT + 6.72.0 google-cloud-spanner diff --git a/grpc-google-cloud-spanner-admin-database-v1/pom.xml b/grpc-google-cloud-spanner-admin-database-v1/pom.xml index 7f6e5c0e32..d316ece2b6 100644 --- a/grpc-google-cloud-spanner-admin-database-v1/pom.xml +++ b/grpc-google-cloud-spanner-admin-database-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-cloud-spanner-admin-database-v1 - 6.71.1-SNAPSHOT + 6.72.0 grpc-google-cloud-spanner-admin-database-v1 GRPC library for grpc-google-cloud-spanner-admin-database-v1 com.google.cloud google-cloud-spanner-parent - 6.71.1-SNAPSHOT + 6.72.0 diff --git a/grpc-google-cloud-spanner-admin-instance-v1/pom.xml b/grpc-google-cloud-spanner-admin-instance-v1/pom.xml index fe49c116d0..d971f88fdc 100644 --- a/grpc-google-cloud-spanner-admin-instance-v1/pom.xml +++ b/grpc-google-cloud-spanner-admin-instance-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-cloud-spanner-admin-instance-v1 - 6.71.1-SNAPSHOT + 6.72.0 grpc-google-cloud-spanner-admin-instance-v1 GRPC library for grpc-google-cloud-spanner-admin-instance-v1 com.google.cloud google-cloud-spanner-parent - 6.71.1-SNAPSHOT + 6.72.0 diff --git a/grpc-google-cloud-spanner-executor-v1/pom.xml b/grpc-google-cloud-spanner-executor-v1/pom.xml index 0030c48500..ac9f792bd3 100644 --- a/grpc-google-cloud-spanner-executor-v1/pom.xml +++ b/grpc-google-cloud-spanner-executor-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-cloud-spanner-executor-v1 - 6.71.1-SNAPSHOT + 6.72.0 grpc-google-cloud-spanner-executor-v1 GRPC library for google-cloud-spanner com.google.cloud google-cloud-spanner-parent - 6.71.1-SNAPSHOT + 6.72.0 diff --git a/grpc-google-cloud-spanner-v1/pom.xml b/grpc-google-cloud-spanner-v1/pom.xml index ace9fd79f0..d7723c6e77 100644 --- a/grpc-google-cloud-spanner-v1/pom.xml +++ b/grpc-google-cloud-spanner-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-cloud-spanner-v1 - 6.71.1-SNAPSHOT + 6.72.0 grpc-google-cloud-spanner-v1 GRPC library for grpc-google-cloud-spanner-v1 com.google.cloud google-cloud-spanner-parent - 6.71.1-SNAPSHOT + 6.72.0 diff --git a/pom.xml b/pom.xml index 8897047df7..955e456f99 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.google.cloud google-cloud-spanner-parent pom - 6.71.1-SNAPSHOT + 6.72.0 Google Cloud Spanner Parent https://github.com/googleapis/java-spanner @@ -61,47 +61,47 @@ com.google.api.grpc proto-google-cloud-spanner-admin-instance-v1 - 6.71.1-SNAPSHOT + 6.72.0 com.google.api.grpc proto-google-cloud-spanner-executor-v1 - 6.71.1-SNAPSHOT + 6.72.0 com.google.api.grpc grpc-google-cloud-spanner-executor-v1 - 6.71.1-SNAPSHOT + 6.72.0 com.google.api.grpc proto-google-cloud-spanner-v1 - 6.71.1-SNAPSHOT + 6.72.0 com.google.api.grpc proto-google-cloud-spanner-admin-database-v1 - 6.71.1-SNAPSHOT + 6.72.0 com.google.api.grpc grpc-google-cloud-spanner-v1 - 6.71.1-SNAPSHOT + 6.72.0 com.google.api.grpc grpc-google-cloud-spanner-admin-instance-v1 - 6.71.1-SNAPSHOT + 6.72.0 com.google.api.grpc grpc-google-cloud-spanner-admin-database-v1 - 6.71.1-SNAPSHOT + 6.72.0 com.google.cloud google-cloud-spanner - 6.71.1-SNAPSHOT + 6.72.0 diff --git a/proto-google-cloud-spanner-admin-database-v1/pom.xml b/proto-google-cloud-spanner-admin-database-v1/pom.xml index 96f7667a71..e9cc23ac3a 100644 --- a/proto-google-cloud-spanner-admin-database-v1/pom.xml +++ b/proto-google-cloud-spanner-admin-database-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-spanner-admin-database-v1 - 6.71.1-SNAPSHOT + 6.72.0 proto-google-cloud-spanner-admin-database-v1 PROTO library for proto-google-cloud-spanner-admin-database-v1 com.google.cloud google-cloud-spanner-parent - 6.71.1-SNAPSHOT + 6.72.0 diff --git a/proto-google-cloud-spanner-admin-instance-v1/pom.xml b/proto-google-cloud-spanner-admin-instance-v1/pom.xml index 22bb2eb1c1..a7d13f01a4 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/pom.xml +++ b/proto-google-cloud-spanner-admin-instance-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-spanner-admin-instance-v1 - 6.71.1-SNAPSHOT + 6.72.0 proto-google-cloud-spanner-admin-instance-v1 PROTO library for proto-google-cloud-spanner-admin-instance-v1 com.google.cloud google-cloud-spanner-parent - 6.71.1-SNAPSHOT + 6.72.0 diff --git a/proto-google-cloud-spanner-executor-v1/pom.xml b/proto-google-cloud-spanner-executor-v1/pom.xml index f4e05e244a..fe38be68ce 100644 --- a/proto-google-cloud-spanner-executor-v1/pom.xml +++ b/proto-google-cloud-spanner-executor-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-spanner-executor-v1 - 6.71.1-SNAPSHOT + 6.72.0 proto-google-cloud-spanner-executor-v1 Proto library for google-cloud-spanner com.google.cloud google-cloud-spanner-parent - 6.71.1-SNAPSHOT + 6.72.0 diff --git a/proto-google-cloud-spanner-v1/pom.xml b/proto-google-cloud-spanner-v1/pom.xml index e554f74792..fce72e6070 100644 --- a/proto-google-cloud-spanner-v1/pom.xml +++ b/proto-google-cloud-spanner-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-spanner-v1 - 6.71.1-SNAPSHOT + 6.72.0 proto-google-cloud-spanner-v1 PROTO library for proto-google-cloud-spanner-v1 com.google.cloud google-cloud-spanner-parent - 6.71.1-SNAPSHOT + 6.72.0 diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml index acf50d15e8..86832f71b9 100644 --- a/samples/snapshot/pom.xml +++ b/samples/snapshot/pom.xml @@ -32,7 +32,7 @@ com.google.cloud google-cloud-spanner - 6.71.1-SNAPSHOT + 6.72.0 diff --git a/versions.txt b/versions.txt index 786797cb74..6cf9f7b626 100644 --- a/versions.txt +++ b/versions.txt @@ -1,13 +1,13 @@ # Format: # module:released-version:current-version -proto-google-cloud-spanner-admin-instance-v1:6.71.0:6.71.1-SNAPSHOT -proto-google-cloud-spanner-v1:6.71.0:6.71.1-SNAPSHOT -proto-google-cloud-spanner-admin-database-v1:6.71.0:6.71.1-SNAPSHOT -grpc-google-cloud-spanner-v1:6.71.0:6.71.1-SNAPSHOT -grpc-google-cloud-spanner-admin-instance-v1:6.71.0:6.71.1-SNAPSHOT -grpc-google-cloud-spanner-admin-database-v1:6.71.0:6.71.1-SNAPSHOT -google-cloud-spanner:6.71.0:6.71.1-SNAPSHOT -google-cloud-spanner-executor:6.71.0:6.71.1-SNAPSHOT -proto-google-cloud-spanner-executor-v1:6.71.0:6.71.1-SNAPSHOT -grpc-google-cloud-spanner-executor-v1:6.71.0:6.71.1-SNAPSHOT +proto-google-cloud-spanner-admin-instance-v1:6.72.0:6.72.0 +proto-google-cloud-spanner-v1:6.72.0:6.72.0 +proto-google-cloud-spanner-admin-database-v1:6.72.0:6.72.0 +grpc-google-cloud-spanner-v1:6.72.0:6.72.0 +grpc-google-cloud-spanner-admin-instance-v1:6.72.0:6.72.0 +grpc-google-cloud-spanner-admin-database-v1:6.72.0:6.72.0 +google-cloud-spanner:6.72.0:6.72.0 +google-cloud-spanner-executor:6.72.0:6.72.0 +proto-google-cloud-spanner-executor-v1:6.72.0:6.72.0 +grpc-google-cloud-spanner-executor-v1:6.72.0:6.72.0 From 7821b07d3c63cafd9573c0256f78fc035785030b Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Wed, 7 Aug 2024 16:21:10 +0200 Subject: [PATCH 30/38] chore(main): release 6.72.1-SNAPSHOT (#3256) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- benchmarks/pom.xml | 2 +- google-cloud-spanner-bom/pom.xml | 18 ++++++++--------- google-cloud-spanner-executor/pom.xml | 4 ++-- google-cloud-spanner/pom.xml | 4 ++-- .../pom.xml | 4 ++-- .../pom.xml | 4 ++-- grpc-google-cloud-spanner-executor-v1/pom.xml | 4 ++-- grpc-google-cloud-spanner-v1/pom.xml | 4 ++-- pom.xml | 20 +++++++++---------- .../pom.xml | 4 ++-- .../pom.xml | 4 ++-- .../pom.xml | 4 ++-- proto-google-cloud-spanner-v1/pom.xml | 4 ++-- samples/snapshot/pom.xml | 2 +- versions.txt | 20 +++++++++---------- 15 files changed, 51 insertions(+), 51 deletions(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index ae700bd337..971cf7023a 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -24,7 +24,7 @@ com.google.cloud google-cloud-spanner-parent - 6.72.0 + 6.72.1-SNAPSHOT diff --git a/google-cloud-spanner-bom/pom.xml b/google-cloud-spanner-bom/pom.xml index fa9e6207a2..7678b407b2 100644 --- a/google-cloud-spanner-bom/pom.xml +++ b/google-cloud-spanner-bom/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.cloud google-cloud-spanner-bom - 6.72.0 + 6.72.1-SNAPSHOT pom com.google.cloud @@ -53,43 +53,43 @@ com.google.cloud google-cloud-spanner - 6.72.0 + 6.72.1-SNAPSHOT com.google.cloud google-cloud-spanner test-jar - 6.72.0 + 6.72.1-SNAPSHOT com.google.api.grpc grpc-google-cloud-spanner-v1 - 6.72.0 + 6.72.1-SNAPSHOT com.google.api.grpc grpc-google-cloud-spanner-admin-instance-v1 - 6.72.0 + 6.72.1-SNAPSHOT com.google.api.grpc grpc-google-cloud-spanner-admin-database-v1 - 6.72.0 + 6.72.1-SNAPSHOT com.google.api.grpc proto-google-cloud-spanner-admin-instance-v1 - 6.72.0 + 6.72.1-SNAPSHOT com.google.api.grpc proto-google-cloud-spanner-v1 - 6.72.0 + 6.72.1-SNAPSHOT com.google.api.grpc proto-google-cloud-spanner-admin-database-v1 - 6.72.0 + 6.72.1-SNAPSHOT diff --git a/google-cloud-spanner-executor/pom.xml b/google-cloud-spanner-executor/pom.xml index 3a99cd0062..62c9474ef2 100644 --- a/google-cloud-spanner-executor/pom.xml +++ b/google-cloud-spanner-executor/pom.xml @@ -5,14 +5,14 @@ 4.0.0 com.google.cloud google-cloud-spanner-executor - 6.72.0 + 6.72.1-SNAPSHOT jar Google Cloud Spanner Executor com.google.cloud google-cloud-spanner-parent - 6.72.0 + 6.72.1-SNAPSHOT diff --git a/google-cloud-spanner/pom.xml b/google-cloud-spanner/pom.xml index 5f42b91fd7..b63f9be06d 100644 --- a/google-cloud-spanner/pom.xml +++ b/google-cloud-spanner/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.cloud google-cloud-spanner - 6.72.0 + 6.72.1-SNAPSHOT jar Google Cloud Spanner https://github.com/googleapis/java-spanner @@ -11,7 +11,7 @@ com.google.cloud google-cloud-spanner-parent - 6.72.0 + 6.72.1-SNAPSHOT google-cloud-spanner diff --git a/grpc-google-cloud-spanner-admin-database-v1/pom.xml b/grpc-google-cloud-spanner-admin-database-v1/pom.xml index d316ece2b6..3f94aa9b0f 100644 --- a/grpc-google-cloud-spanner-admin-database-v1/pom.xml +++ b/grpc-google-cloud-spanner-admin-database-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-cloud-spanner-admin-database-v1 - 6.72.0 + 6.72.1-SNAPSHOT grpc-google-cloud-spanner-admin-database-v1 GRPC library for grpc-google-cloud-spanner-admin-database-v1 com.google.cloud google-cloud-spanner-parent - 6.72.0 + 6.72.1-SNAPSHOT diff --git a/grpc-google-cloud-spanner-admin-instance-v1/pom.xml b/grpc-google-cloud-spanner-admin-instance-v1/pom.xml index d971f88fdc..1fd3088a15 100644 --- a/grpc-google-cloud-spanner-admin-instance-v1/pom.xml +++ b/grpc-google-cloud-spanner-admin-instance-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-cloud-spanner-admin-instance-v1 - 6.72.0 + 6.72.1-SNAPSHOT grpc-google-cloud-spanner-admin-instance-v1 GRPC library for grpc-google-cloud-spanner-admin-instance-v1 com.google.cloud google-cloud-spanner-parent - 6.72.0 + 6.72.1-SNAPSHOT diff --git a/grpc-google-cloud-spanner-executor-v1/pom.xml b/grpc-google-cloud-spanner-executor-v1/pom.xml index ac9f792bd3..76fce9b99b 100644 --- a/grpc-google-cloud-spanner-executor-v1/pom.xml +++ b/grpc-google-cloud-spanner-executor-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-cloud-spanner-executor-v1 - 6.72.0 + 6.72.1-SNAPSHOT grpc-google-cloud-spanner-executor-v1 GRPC library for google-cloud-spanner com.google.cloud google-cloud-spanner-parent - 6.72.0 + 6.72.1-SNAPSHOT diff --git a/grpc-google-cloud-spanner-v1/pom.xml b/grpc-google-cloud-spanner-v1/pom.xml index d7723c6e77..239a219a91 100644 --- a/grpc-google-cloud-spanner-v1/pom.xml +++ b/grpc-google-cloud-spanner-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-cloud-spanner-v1 - 6.72.0 + 6.72.1-SNAPSHOT grpc-google-cloud-spanner-v1 GRPC library for grpc-google-cloud-spanner-v1 com.google.cloud google-cloud-spanner-parent - 6.72.0 + 6.72.1-SNAPSHOT diff --git a/pom.xml b/pom.xml index 955e456f99..519caf49a4 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.google.cloud google-cloud-spanner-parent pom - 6.72.0 + 6.72.1-SNAPSHOT Google Cloud Spanner Parent https://github.com/googleapis/java-spanner @@ -61,47 +61,47 @@ com.google.api.grpc proto-google-cloud-spanner-admin-instance-v1 - 6.72.0 + 6.72.1-SNAPSHOT com.google.api.grpc proto-google-cloud-spanner-executor-v1 - 6.72.0 + 6.72.1-SNAPSHOT com.google.api.grpc grpc-google-cloud-spanner-executor-v1 - 6.72.0 + 6.72.1-SNAPSHOT com.google.api.grpc proto-google-cloud-spanner-v1 - 6.72.0 + 6.72.1-SNAPSHOT com.google.api.grpc proto-google-cloud-spanner-admin-database-v1 - 6.72.0 + 6.72.1-SNAPSHOT com.google.api.grpc grpc-google-cloud-spanner-v1 - 6.72.0 + 6.72.1-SNAPSHOT com.google.api.grpc grpc-google-cloud-spanner-admin-instance-v1 - 6.72.0 + 6.72.1-SNAPSHOT com.google.api.grpc grpc-google-cloud-spanner-admin-database-v1 - 6.72.0 + 6.72.1-SNAPSHOT com.google.cloud google-cloud-spanner - 6.72.0 + 6.72.1-SNAPSHOT diff --git a/proto-google-cloud-spanner-admin-database-v1/pom.xml b/proto-google-cloud-spanner-admin-database-v1/pom.xml index e9cc23ac3a..f900558462 100644 --- a/proto-google-cloud-spanner-admin-database-v1/pom.xml +++ b/proto-google-cloud-spanner-admin-database-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-spanner-admin-database-v1 - 6.72.0 + 6.72.1-SNAPSHOT proto-google-cloud-spanner-admin-database-v1 PROTO library for proto-google-cloud-spanner-admin-database-v1 com.google.cloud google-cloud-spanner-parent - 6.72.0 + 6.72.1-SNAPSHOT diff --git a/proto-google-cloud-spanner-admin-instance-v1/pom.xml b/proto-google-cloud-spanner-admin-instance-v1/pom.xml index a7d13f01a4..507fe2e57a 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/pom.xml +++ b/proto-google-cloud-spanner-admin-instance-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-spanner-admin-instance-v1 - 6.72.0 + 6.72.1-SNAPSHOT proto-google-cloud-spanner-admin-instance-v1 PROTO library for proto-google-cloud-spanner-admin-instance-v1 com.google.cloud google-cloud-spanner-parent - 6.72.0 + 6.72.1-SNAPSHOT diff --git a/proto-google-cloud-spanner-executor-v1/pom.xml b/proto-google-cloud-spanner-executor-v1/pom.xml index fe38be68ce..f4dc5b5bf2 100644 --- a/proto-google-cloud-spanner-executor-v1/pom.xml +++ b/proto-google-cloud-spanner-executor-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-spanner-executor-v1 - 6.72.0 + 6.72.1-SNAPSHOT proto-google-cloud-spanner-executor-v1 Proto library for google-cloud-spanner com.google.cloud google-cloud-spanner-parent - 6.72.0 + 6.72.1-SNAPSHOT diff --git a/proto-google-cloud-spanner-v1/pom.xml b/proto-google-cloud-spanner-v1/pom.xml index fce72e6070..c0c5da690a 100644 --- a/proto-google-cloud-spanner-v1/pom.xml +++ b/proto-google-cloud-spanner-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-spanner-v1 - 6.72.0 + 6.72.1-SNAPSHOT proto-google-cloud-spanner-v1 PROTO library for proto-google-cloud-spanner-v1 com.google.cloud google-cloud-spanner-parent - 6.72.0 + 6.72.1-SNAPSHOT diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml index 86832f71b9..df9f082403 100644 --- a/samples/snapshot/pom.xml +++ b/samples/snapshot/pom.xml @@ -32,7 +32,7 @@ com.google.cloud google-cloud-spanner - 6.72.0 + 6.72.1-SNAPSHOT diff --git a/versions.txt b/versions.txt index 6cf9f7b626..1fa5cb386e 100644 --- a/versions.txt +++ b/versions.txt @@ -1,13 +1,13 @@ # Format: # module:released-version:current-version -proto-google-cloud-spanner-admin-instance-v1:6.72.0:6.72.0 -proto-google-cloud-spanner-v1:6.72.0:6.72.0 -proto-google-cloud-spanner-admin-database-v1:6.72.0:6.72.0 -grpc-google-cloud-spanner-v1:6.72.0:6.72.0 -grpc-google-cloud-spanner-admin-instance-v1:6.72.0:6.72.0 -grpc-google-cloud-spanner-admin-database-v1:6.72.0:6.72.0 -google-cloud-spanner:6.72.0:6.72.0 -google-cloud-spanner-executor:6.72.0:6.72.0 -proto-google-cloud-spanner-executor-v1:6.72.0:6.72.0 -grpc-google-cloud-spanner-executor-v1:6.72.0:6.72.0 +proto-google-cloud-spanner-admin-instance-v1:6.72.0:6.72.1-SNAPSHOT +proto-google-cloud-spanner-v1:6.72.0:6.72.1-SNAPSHOT +proto-google-cloud-spanner-admin-database-v1:6.72.0:6.72.1-SNAPSHOT +grpc-google-cloud-spanner-v1:6.72.0:6.72.1-SNAPSHOT +grpc-google-cloud-spanner-admin-instance-v1:6.72.0:6.72.1-SNAPSHOT +grpc-google-cloud-spanner-admin-database-v1:6.72.0:6.72.1-SNAPSHOT +google-cloud-spanner:6.72.0:6.72.1-SNAPSHOT +google-cloud-spanner-executor:6.72.0:6.72.1-SNAPSHOT +proto-google-cloud-spanner-executor-v1:6.72.0:6.72.1-SNAPSHOT +grpc-google-cloud-spanner-executor-v1:6.72.0:6.72.1-SNAPSHOT From 17a4440c0feb2f2acbed88c6da5c1493d7002a2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Olav=20L=C3=B8ite?= Date: Wed, 7 Aug 2024 16:31:25 +0200 Subject: [PATCH 31/38] chore: unflake ITAsyncAPITest.invalidDatabase (#3257) Fixes #3255 --- .../cloud/spanner/it/ITAsyncAPITest.java | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITAsyncAPITest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITAsyncAPITest.java index 1e408fadf3..1ca69fe975 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITAsyncAPITest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITAsyncAPITest.java @@ -58,6 +58,7 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.ThreadLocalRandom; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; @@ -237,17 +238,24 @@ public void invalidDatabase() throws Exception { RemoteSpannerHelper helper = env.getTestHelper(); DatabaseClient invalidClient = helper.getClient().getDatabaseClient(DatabaseId.of(helper.getInstanceId(), "invalid")); - ApiFuture row = - invalidClient - .singleUse(TimestampBound.strong()) - .readRowAsync(TABLE_NAME, Key.of("k99"), ALL_COLUMNS); + Thread.sleep(ThreadLocalRandom.current().nextLong(100L)); try { + // The NOT_FOUND error can come from both the call to invalidClient.singleUse() as well as + // from the call to row.get(), which is why both need to be inside the try block. + ApiFuture row = + invalidClient + .singleUse(TimestampBound.strong()) + .readRowAsync(TABLE_NAME, Key.of("k99"), ALL_COLUMNS); row.get(); fail("missing expected exception"); - } catch (ExecutionException e) { - assertThat(e.getCause()).isInstanceOf(SpannerException.class); - SpannerException se = (SpannerException) e.getCause(); - assertThat(se.getErrorCode()).isEqualTo(ErrorCode.NOT_FOUND); + } catch (ExecutionException | SpannerException thrownException) { + SpannerException spannerException; + if (thrownException instanceof ExecutionException) { + spannerException = (SpannerException) thrownException.getCause(); + } else { + spannerException = (SpannerException) thrownException; + } + assertEquals(ErrorCode.NOT_FOUND, spannerException.getErrorCode()); } } From 254a94cc7051ab99df6a96356d3576f5a1f792b7 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Wed, 7 Aug 2024 17:09:24 +0200 Subject: [PATCH 32/38] chore(deps): update dependency com.google.cloud:google-cloud-spanner to v6.72.0 (#3261) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore(deps): update dependency com.google.cloud:google-cloud-spanner to v6.69.0 * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --------- Co-authored-by: Owl Bot Co-authored-by: Knut Olav Løite From b6b48b9e6242bb7425da2b956f15bc06f45180a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Olav=20L=C3=B8ite?= Date: Thu, 8 Aug 2024 08:51:48 +0200 Subject: [PATCH 33/38] chore: unflake blockAndTimeoutOnPoolExhaustion_withAcquireSessionTimeout (#3252) Fixes 3251 --- .../google/cloud/spanner/SessionPoolTest.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolTest.java index 58b0280cf0..f443086119 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolTest.java @@ -1294,7 +1294,7 @@ public void blockAndTimeoutOnPoolExhaustion_withAcquireSessionTimeout() throws E .setMinSessions(minSessions) .setMaxSessions(1) .setInitialWaitForSessionTimeoutMillis(20L) - .setAcquireSessionTimeout(Duration.ofMillis(20L)) + .setAcquireSessionTimeout(null) .build(); setupMockSessionCreation(); pool = createPool(); @@ -1307,18 +1307,18 @@ public void blockAndTimeoutOnPoolExhaustion_withAcquireSessionTimeout() throws E Future fut = executor.submit( () -> { - latch.countDown(); PooledSessionFuture session = pool.getSession(); + latch.countDown(); + session.get(); session.close(); return null; }); // Wait until the background thread is actually waiting for a session. latch.await(); // Wait until the request has timed out. - int waitCount = 0; - while (pool.getNumWaiterTimeouts() == 0L && waitCount < 5000) { - Thread.sleep(1L); - waitCount++; + Stopwatch watch = Stopwatch.createStarted(); + while (pool.getNumWaiterTimeouts() == 0L && watch.elapsed(TimeUnit.MILLISECONDS) < 1000) { + Thread.yield(); } // Return the checked out session to the pool so the async request will get a session and // finish. @@ -1326,10 +1326,11 @@ public void blockAndTimeoutOnPoolExhaustion_withAcquireSessionTimeout() throws E // Verify that the async request also succeeds. fut.get(10L, TimeUnit.SECONDS); executor.shutdown(); + assertTrue(executor.awaitTermination(10L, TimeUnit.SECONDS)); // Verify that the session was returned to the pool and that we can get it again. - Session session = pool.getSession(); - assertThat(session).isNotNull(); + PooledSessionFuture session = pool.getSession(); + assertThat(session.get()).isNotNull(); session.close(); assertThat(pool.getNumWaiterTimeouts()).isAtLeast(1L); } From a843317a744db85c16594cbd566602d7fb72703e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Olav=20L=C3=B8ite?= Date: Thu, 8 Aug 2024 08:52:17 +0200 Subject: [PATCH 34/38] chore: unflake OpenTelemetrySpanTest.transactionRunnerWithFailedAndBeginTransaction (#3254) Fixes #3253 --- .../cloud/spanner/OpenTelemetrySpanTest.java | 31 ++++++++----------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/OpenTelemetrySpanTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/OpenTelemetrySpanTest.java index c309932f0b..a2aeb88773 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/OpenTelemetrySpanTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/OpenTelemetrySpanTest.java @@ -572,22 +572,13 @@ public void transactionRunnerWithError() { @Test public void transactionRunnerWithFailedAndBeginTransaction() { List expectedReadWriteTransactionWithCommitAndBeginTransactionSpans = - isMultiplexedSessionsEnabled() - ? ImmutableList.of( - "CloudSpannerOperation.CreateMultiplexedSession", - "CloudSpannerOperation.BeginTransaction", - "CloudSpannerOperation.BatchCreateSessionsRequest", - "CloudSpannerOperation.ExecuteUpdate", - "CloudSpannerOperation.Commit", - "CloudSpannerOperation.BatchCreateSessions", - "CloudSpanner.ReadWriteTransaction") - : ImmutableList.of( - "CloudSpannerOperation.BeginTransaction", - "CloudSpannerOperation.BatchCreateSessionsRequest", - "CloudSpannerOperation.ExecuteUpdate", - "CloudSpannerOperation.Commit", - "CloudSpannerOperation.BatchCreateSessions", - "CloudSpanner.ReadWriteTransaction"); + ImmutableList.of( + "CloudSpannerOperation.BeginTransaction", + "CloudSpannerOperation.BatchCreateSessionsRequest", + "CloudSpannerOperation.ExecuteUpdate", + "CloudSpannerOperation.Commit", + "CloudSpannerOperation.BatchCreateSessions", + "CloudSpanner.ReadWriteTransaction"); DatabaseClient client = getClient(); assertEquals( Long.valueOf(1L), @@ -612,7 +603,7 @@ public void transactionRunnerWithFailedAndBeginTransaction() { Stopwatch stopwatch = Stopwatch.createStarted(); while (spanExporter.getFinishedSpanItems().size() < expectedReadWriteTransactionWithCommitAndBeginTransactionSpans.size() - && stopwatch.elapsed().compareTo(java.time.Duration.ofMillis(1000)) < 0) { + && stopwatch.elapsed(TimeUnit.MILLISECONDS) < 2000) { Thread.yield(); } @@ -621,7 +612,11 @@ public void transactionRunnerWithFailedAndBeginTransaction() { .getFinishedSpanItems() .forEach( spanItem -> { - actualSpanItems.add(spanItem.getName()); + // Ignore multiplexed sessions, as they are not used by this test and can therefore + // best be ignored, as it is not 100% certain that it has already been created. + if (!"CloudSpannerOperation.CreateMultiplexedSession".equals(spanItem.getName())) { + actualSpanItems.add(spanItem.getName()); + } switch (spanItem.getName()) { case "CloudSpannerOperation.CreateMultiplexedSession": verifyRequestEvents( From 1eb5a31912abec13f0b73fd5229a297a34624a12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Olav=20L=C3=B8ite?= Date: Thu, 8 Aug 2024 08:54:33 +0200 Subject: [PATCH 35/38] chore: unflake asyncTransactionManagerWaitsUntilAsyncBatchUpdateHasFinished (#3258) Fixes #3241 --- .../spanner/AsyncTransactionManagerTest.java | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncTransactionManagerTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncTransactionManagerTest.java index 7318e6e2c3..863c731c19 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncTransactionManagerTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncTransactionManagerTest.java @@ -46,6 +46,7 @@ import com.google.common.collect.Range; import com.google.common.util.concurrent.MoreExecutors; import com.google.protobuf.AbstractMessage; +import com.google.protobuf.GeneratedMessageV3; import com.google.spanner.v1.BatchCreateSessionsRequest; import com.google.spanner.v1.BeginTransactionRequest; import com.google.spanner.v1.CommitRequest; @@ -983,17 +984,13 @@ public void asyncTransactionManagerWaitsUntilAsyncBatchUpdateHasFinished() throw } } } + ImmutableList> expectedRequests = + ImmutableList.of( + BatchCreateSessionsRequest.class, ExecuteBatchDmlRequest.class, CommitRequest.class); if (isMultiplexedSessionsEnabled()) { - assertThat(mockSpanner.getRequestTypes()) - .containsExactly( - CreateSessionRequest.class, - BatchCreateSessionsRequest.class, - ExecuteBatchDmlRequest.class, - CommitRequest.class); + assertThat(mockSpanner.getRequestTypes()).containsAtLeastElementsIn(expectedRequests); } else { - assertThat(mockSpanner.getRequestTypes()) - .containsExactly( - BatchCreateSessionsRequest.class, ExecuteBatchDmlRequest.class, CommitRequest.class); + assertThat(mockSpanner.getRequestTypes()).containsExactlyElementsIn(expectedRequests); } } From 41673d7a3ee69186e365d6993ba72a854280d4b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Olav=20L=C3=B8ite?= Date: Thu, 8 Aug 2024 08:54:45 +0200 Subject: [PATCH 36/38] chore: unflake AsyncTransactionManagerTests (#3259) Fixes #3240 --- .../spanner/AsyncTransactionManagerTest.java | 151 +++++++----------- 1 file changed, 56 insertions(+), 95 deletions(-) diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncTransactionManagerTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncTransactionManagerTest.java index 863c731c19..9b05a18d71 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncTransactionManagerTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncTransactionManagerTest.java @@ -346,33 +346,22 @@ public void asyncTransactionManagerFireAndForgetInvalidUpdate() throws Exception } } } + ImmutableList> expectedRequests = + ImmutableList.of( + BatchCreateSessionsRequest.class, + // The first update that fails. This will cause a transaction retry. + ExecuteSqlRequest.class, + // The retry will use an explicit BeginTransaction call. + BeginTransactionRequest.class, + // The first update will again fail, but now there is a transaction id, so the + // transaction can continue. + ExecuteSqlRequest.class, + ExecuteSqlRequest.class, + CommitRequest.class); if (isMultiplexedSessionsEnabled()) { - assertThat(mockSpanner.getRequestTypes()) - .containsExactly( - CreateSessionRequest.class, - BatchCreateSessionsRequest.class, - // The first update that fails. This will cause a transaction retry. - ExecuteSqlRequest.class, - // The retry will use an explicit BeginTransaction call. - BeginTransactionRequest.class, - // The first update will again fail, but now there is a transaction id, so the - // transaction can continue. - ExecuteSqlRequest.class, - ExecuteSqlRequest.class, - CommitRequest.class); + assertThat(mockSpanner.getRequestTypes()).containsAtLeastElementsIn(expectedRequests); } else { - assertThat(mockSpanner.getRequestTypes()) - .containsExactly( - BatchCreateSessionsRequest.class, - // The first update that fails. This will cause a transaction retry. - ExecuteSqlRequest.class, - // The retry will use an explicit BeginTransaction call. - BeginTransactionRequest.class, - // The first update will again fail, but now there is a transaction id, so the - // transaction can continue. - ExecuteSqlRequest.class, - ExecuteSqlRequest.class, - CommitRequest.class); + assertThat(mockSpanner.getRequestTypes()).containsExactlyElementsIn(expectedRequests); } } @@ -682,21 +671,16 @@ public void asyncTransactionManagerFireAndForgetInvalidBatchUpdate() throws Exce } } } + ImmutableList> expectedRequests = + ImmutableList.of( + BatchCreateSessionsRequest.class, + ExecuteBatchDmlRequest.class, + ExecuteBatchDmlRequest.class, + CommitRequest.class); if (isMultiplexedSessionsEnabled()) { - assertThat(mockSpanner.getRequestTypes()) - .containsExactly( - CreateSessionRequest.class, - BatchCreateSessionsRequest.class, - ExecuteBatchDmlRequest.class, - ExecuteBatchDmlRequest.class, - CommitRequest.class); + assertThat(mockSpanner.getRequestTypes()).containsAtLeastElementsIn(expectedRequests); } else { - assertThat(mockSpanner.getRequestTypes()) - .containsExactly( - BatchCreateSessionsRequest.class, - ExecuteBatchDmlRequest.class, - ExecuteBatchDmlRequest.class, - CommitRequest.class); + assertThat(mockSpanner.getRequestTypes()).containsExactlyElementsIn(expectedRequests); } } @@ -730,23 +714,17 @@ public void asyncTransactionManagerBatchUpdateAborted() throws Exception { assertThat(attempt.get()).isEqualTo(2); // There should only be 1 CommitRequest, as the first attempt should abort already after the // ExecuteBatchDmlRequest. + ImmutableList> expectedRequests = + ImmutableList.of( + BatchCreateSessionsRequest.class, + ExecuteBatchDmlRequest.class, + BeginTransactionRequest.class, + ExecuteBatchDmlRequest.class, + CommitRequest.class); if (isMultiplexedSessionsEnabled()) { - assertThat(mockSpanner.getRequestTypes()) - .containsExactly( - CreateSessionRequest.class, - BatchCreateSessionsRequest.class, - ExecuteBatchDmlRequest.class, - BeginTransactionRequest.class, - ExecuteBatchDmlRequest.class, - CommitRequest.class); + assertThat(mockSpanner.getRequestTypes()).containsAtLeastElementsIn(expectedRequests); } else { - assertThat(mockSpanner.getRequestTypes()) - .containsExactly( - BatchCreateSessionsRequest.class, - ExecuteBatchDmlRequest.class, - BeginTransactionRequest.class, - ExecuteBatchDmlRequest.class, - CommitRequest.class); + assertThat(mockSpanner.getRequestTypes()).containsExactlyElementsIn(expectedRequests); } } @@ -778,23 +756,17 @@ public void asyncTransactionManagerBatchUpdateAbortedBeforeFirstStatement() thro assertThat(attempt.get()).isEqualTo(2); // There should only be 1 CommitRequest, as the first attempt should abort already after the // ExecuteBatchDmlRequest. + ImmutableList> expectedRequests = + ImmutableList.of( + BatchCreateSessionsRequest.class, + ExecuteBatchDmlRequest.class, + BeginTransactionRequest.class, + ExecuteBatchDmlRequest.class, + CommitRequest.class); if (isMultiplexedSessionsEnabled()) { - assertThat(mockSpanner.getRequestTypes()) - .containsExactly( - CreateSessionRequest.class, - BatchCreateSessionsRequest.class, - ExecuteBatchDmlRequest.class, - BeginTransactionRequest.class, - ExecuteBatchDmlRequest.class, - CommitRequest.class); + assertThat(mockSpanner.getRequestTypes()).containsAtLeastElementsIn(expectedRequests); } else { - assertThat(mockSpanner.getRequestTypes()) - .containsExactly( - BatchCreateSessionsRequest.class, - ExecuteBatchDmlRequest.class, - BeginTransactionRequest.class, - ExecuteBatchDmlRequest.class, - CommitRequest.class); + assertThat(mockSpanner.getRequestTypes()).containsExactlyElementsIn(expectedRequests); } } @@ -844,25 +816,18 @@ public void asyncTransactionManagerWithBatchUpdateCommitAborted() throws Excepti } finally { mockSpanner.putStatementResult(StatementResult.update(UPDATE_STATEMENT, UPDATE_COUNT)); } + ImmutableList> expectedRequests = + ImmutableList.of( + BatchCreateSessionsRequest.class, + ExecuteBatchDmlRequest.class, + CommitRequest.class, + BeginTransactionRequest.class, + ExecuteBatchDmlRequest.class, + CommitRequest.class); if (isMultiplexedSessionsEnabled()) { - assertThat(mockSpanner.getRequestTypes()) - .containsExactly( - CreateSessionRequest.class, - BatchCreateSessionsRequest.class, - ExecuteBatchDmlRequest.class, - CommitRequest.class, - BeginTransactionRequest.class, - ExecuteBatchDmlRequest.class, - CommitRequest.class); + assertThat(mockSpanner.getRequestTypes()).containsAtLeastElementsIn(expectedRequests); } else { - assertThat(mockSpanner.getRequestTypes()) - .containsExactly( - BatchCreateSessionsRequest.class, - ExecuteBatchDmlRequest.class, - CommitRequest.class, - BeginTransactionRequest.class, - ExecuteBatchDmlRequest.class, - CommitRequest.class); + assertThat(mockSpanner.getRequestTypes()).containsExactlyElementsIn(expectedRequests); } } @@ -926,7 +891,7 @@ public void asyncTransactionManagerBatchUpdateAbortedWithoutGettingResult() thro } @Test - public void asyncTransactionManagerWithBatchUpdateCommitFails() throws Exception { + public void asyncTransactionManagerWithBatchUpdateCommitFails() { mockSpanner.setCommitExecutionTime( SimulatedExecutionTime.ofException( Status.INVALID_ARGUMENT @@ -949,17 +914,13 @@ public void asyncTransactionManagerWithBatchUpdateCommitFails() throws Exception assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); assertThat(e.getMessage()).contains("mutation limit exceeded"); } + ImmutableList> expectedRequests = + ImmutableList.of( + BatchCreateSessionsRequest.class, ExecuteBatchDmlRequest.class, CommitRequest.class); if (isMultiplexedSessionsEnabled()) { - assertThat(mockSpanner.getRequestTypes()) - .containsExactly( - CreateSessionRequest.class, - BatchCreateSessionsRequest.class, - ExecuteBatchDmlRequest.class, - CommitRequest.class); + assertThat(mockSpanner.getRequestTypes()).containsAtLeastElementsIn(expectedRequests); } else { - assertThat(mockSpanner.getRequestTypes()) - .containsExactly( - BatchCreateSessionsRequest.class, ExecuteBatchDmlRequest.class, CommitRequest.class); + assertThat(mockSpanner.getRequestTypes()).containsExactlyElementsIn(expectedRequests); } } From b44104ff41214f310c5d906550755dbcbbe37f55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Olav=20L=C3=B8ite?= Date: Thu, 8 Aug 2024 08:54:59 +0200 Subject: [PATCH 37/38] chore: unflake ITAutogeneratedAdminClientTest (#3260) Fixes #3239 --- .../cloud/spanner/it/ITAutogeneratedAdminClientTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITAutogeneratedAdminClientTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITAutogeneratedAdminClientTest.java index a1c6a35819..de5597da4f 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITAutogeneratedAdminClientTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITAutogeneratedAdminClientTest.java @@ -266,9 +266,9 @@ private Database createAndUpdateDatabase( private String getCreateTableStatement() { if (dialect == DatabaseDialect.POSTGRESQL) { - return "CREATE TABLE T (" + " \"K\" VARCHAR PRIMARY KEY" + ")"; + return "CREATE TABLE IF NOT EXISTS T (" + " \"K\" VARCHAR PRIMARY KEY" + ")"; } else { - return "CREATE TABLE T (" + " K STRING(MAX)" + ") PRIMARY KEY (K)"; + return "CREATE TABLE IF NOT EXISTS T (" + " K STRING(MAX)" + ") PRIMARY KEY (K)"; } } From a9423c0155708e65fd90c2eebd978a103129c335 Mon Sep 17 00:00:00 2001 From: diegomarquezp Date: Fri, 16 Aug 2024 15:20:54 +0000 Subject: [PATCH 38/38] chore: secure hermetic build workflow --- .github/workflows/hermetic_library_generation.yaml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/hermetic_library_generation.yaml b/.github/workflows/hermetic_library_generation.yaml index 7146cc3dc1..8b479f3a45 100644 --- a/.github/workflows/hermetic_library_generation.yaml +++ b/.github/workflows/hermetic_library_generation.yaml @@ -17,9 +17,12 @@ name: Hermetic library generation upon generation config change through pull req on: pull_request: +env: + HEAD_REF: ${{ github.head_ref }} + jobs: library_generation: - # skip pull requests coming from a forked repository + # skip pull requests come from a forked repository if: github.event.pull_request.head.repo.full_name == github.repository runs-on: ubuntu-latest steps: @@ -35,6 +38,6 @@ jobs: [ -z "$(git config user.name)" ] && git config --global user.name "cloud-java-bot" bash .github/scripts/hermetic_library_generation.sh \ --target_branch ${{ github.base_ref }} \ - --current_branch ${{ github.head_ref }} + --current_branch $HEAD_REF env: GH_TOKEN: ${{ secrets.CLOUD_JAVA_BOT_TOKEN }}