diff --git a/driver/src/main/java/org/neo4j/driver/internal/DriverFactory.java b/driver/src/main/java/org/neo4j/driver/internal/DriverFactory.java index c7acd34b8b..1aa87743bd 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/DriverFactory.java +++ b/driver/src/main/java/org/neo4j/driver/internal/DriverFactory.java @@ -27,6 +27,7 @@ import io.netty.util.concurrent.EventExecutorGroup; import io.netty.util.internal.logging.InternalLoggerFactory; import java.net.URI; +import java.time.Clock; import java.util.Objects; import java.util.function.Supplier; import org.neo4j.driver.AuthToken; @@ -59,7 +60,6 @@ import org.neo4j.driver.internal.security.SecurityPlans; import org.neo4j.driver.internal.spi.ConnectionPool; import org.neo4j.driver.internal.spi.ConnectionProvider; -import org.neo4j.driver.internal.util.Clock; import org.neo4j.driver.internal.util.Futures; import org.neo4j.driver.net.ServerAddressResolver; @@ -336,7 +336,7 @@ private static ServerAddressResolver createResolver(Config config) { * Creates new {@link Clock}. */ protected Clock createClock() { - return Clock.SYSTEM; + return Clock.systemUTC(); } /** diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/NetworkConnection.java b/driver/src/main/java/org/neo4j/driver/internal/async/NetworkConnection.java index 272cf64525..5e4fb4883d 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/NetworkConnection.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/NetworkConnection.java @@ -25,6 +25,7 @@ import io.netty.channel.Channel; import io.netty.channel.ChannelHandler; +import java.time.Clock; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; import java.util.concurrent.TimeUnit; @@ -45,7 +46,6 @@ import org.neo4j.driver.internal.metrics.MetricsListener; import org.neo4j.driver.internal.spi.Connection; import org.neo4j.driver.internal.spi.ResponseHandler; -import org.neo4j.driver.internal.util.Clock; /** * This connection represents a simple network connection to a remote server. It wraps a channel obtained from a connection pool. The life cycle of this diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/connection/ChannelConnectorImpl.java b/driver/src/main/java/org/neo4j/driver/internal/async/connection/ChannelConnectorImpl.java index 32630d6450..3cdd1cdc07 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/connection/ChannelConnectorImpl.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/connection/ChannelConnectorImpl.java @@ -29,6 +29,7 @@ import io.netty.resolver.AddressResolverGroup; import java.net.InetSocketAddress; import java.net.SocketAddress; +import java.time.Clock; import org.neo4j.driver.AuthToken; import org.neo4j.driver.AuthTokens; import org.neo4j.driver.Logging; @@ -40,7 +41,6 @@ import org.neo4j.driver.internal.cluster.RoutingContext; import org.neo4j.driver.internal.security.InternalAuthToken; import org.neo4j.driver.internal.security.SecurityPlan; -import org.neo4j.driver.internal.util.Clock; public class ChannelConnectorImpl implements ChannelConnector { private final String userAgent; diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/connection/NettyChannelInitializer.java b/driver/src/main/java/org/neo4j/driver/internal/async/connection/NettyChannelInitializer.java index 0bb96e5e59..eea5d2f22d 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/connection/NettyChannelInitializer.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/connection/NettyChannelInitializer.java @@ -25,6 +25,7 @@ import io.netty.channel.Channel; import io.netty.channel.ChannelInitializer; import io.netty.handler.ssl.SslHandler; +import java.time.Clock; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLParameters; @@ -32,7 +33,6 @@ import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.async.inbound.InboundMessageDispatcher; import org.neo4j.driver.internal.security.SecurityPlan; -import org.neo4j.driver.internal.util.Clock; public class NettyChannelInitializer extends ChannelInitializer { private final BoltServerAddress address; diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/pool/ConnectionPoolImpl.java b/driver/src/main/java/org/neo4j/driver/internal/async/pool/ConnectionPoolImpl.java index 1a3c360feb..ec309e4c3f 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/pool/ConnectionPoolImpl.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/pool/ConnectionPoolImpl.java @@ -28,6 +28,7 @@ import io.netty.bootstrap.Bootstrap; import io.netty.channel.Channel; import io.netty.channel.EventLoopGroup; +import java.time.Clock; import java.util.HashMap; import java.util.Iterator; import java.util.Map; @@ -50,7 +51,6 @@ import org.neo4j.driver.internal.metrics.MetricsListener; import org.neo4j.driver.internal.spi.Connection; import org.neo4j.driver.internal.spi.ConnectionPool; -import org.neo4j.driver.internal.util.Clock; import org.neo4j.driver.internal.util.Futures; import org.neo4j.driver.net.ServerAddress; diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/pool/NettyChannelHealthChecker.java b/driver/src/main/java/org/neo4j/driver/internal/async/pool/NettyChannelHealthChecker.java index b5e4c5ef34..4a7a0c28db 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/pool/NettyChannelHealthChecker.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/pool/NettyChannelHealthChecker.java @@ -26,6 +26,7 @@ import io.netty.channel.pool.ChannelHealthChecker; import io.netty.util.concurrent.Future; import io.netty.util.concurrent.Promise; +import java.time.Clock; import java.util.Optional; import java.util.concurrent.atomic.AtomicReference; import org.neo4j.driver.Logger; @@ -34,7 +35,6 @@ import org.neo4j.driver.internal.async.connection.AuthorizationStateListener; import org.neo4j.driver.internal.handlers.PingResponseHandler; import org.neo4j.driver.internal.messaging.request.ResetMessage; -import org.neo4j.driver.internal.util.Clock; public class NettyChannelHealthChecker implements ChannelHealthChecker, AuthorizationStateListener { private final PoolSettings poolSettings; diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/pool/NetworkConnectionFactory.java b/driver/src/main/java/org/neo4j/driver/internal/async/pool/NetworkConnectionFactory.java index 288eb717ac..7480218aae 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/pool/NetworkConnectionFactory.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/pool/NetworkConnectionFactory.java @@ -19,11 +19,11 @@ package org.neo4j.driver.internal.async.pool; import io.netty.channel.Channel; +import java.time.Clock; import org.neo4j.driver.Logging; import org.neo4j.driver.internal.async.NetworkConnection; import org.neo4j.driver.internal.metrics.MetricsListener; import org.neo4j.driver.internal.spi.Connection; -import org.neo4j.driver.internal.util.Clock; public class NetworkConnectionFactory implements ConnectionFactory { private final Clock clock; diff --git a/driver/src/main/java/org/neo4j/driver/internal/cluster/ClusterRoutingTable.java b/driver/src/main/java/org/neo4j/driver/internal/cluster/ClusterRoutingTable.java index 43f91237be..2ae5159f6a 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/cluster/ClusterRoutingTable.java +++ b/driver/src/main/java/org/neo4j/driver/internal/cluster/ClusterRoutingTable.java @@ -22,6 +22,7 @@ import static java.util.Arrays.asList; import static org.neo4j.driver.internal.util.LockUtil.executeWithLock; +import java.time.Clock; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; @@ -34,7 +35,6 @@ import org.neo4j.driver.AccessMode; import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.DatabaseName; -import org.neo4j.driver.internal.util.Clock; public class ClusterRoutingTable implements RoutingTable { private static final int MIN_ROUTERS = 1; diff --git a/driver/src/main/java/org/neo4j/driver/internal/cluster/RoutingProcedureClusterCompositionProvider.java b/driver/src/main/java/org/neo4j/driver/internal/cluster/RoutingProcedureClusterCompositionProvider.java index fc88df9580..765122836c 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/cluster/RoutingProcedureClusterCompositionProvider.java +++ b/driver/src/main/java/org/neo4j/driver/internal/cluster/RoutingProcedureClusterCompositionProvider.java @@ -22,6 +22,7 @@ import static org.neo4j.driver.internal.messaging.request.MultiDatabaseUtil.supportsMultiDatabase; import static org.neo4j.driver.internal.messaging.request.MultiDatabaseUtil.supportsRouteMessage; +import java.time.Clock; import java.util.List; import java.util.Set; import java.util.concurrent.CompletionException; @@ -33,7 +34,6 @@ import org.neo4j.driver.exceptions.value.ValueException; import org.neo4j.driver.internal.DatabaseName; import org.neo4j.driver.internal.spi.Connection; -import org.neo4j.driver.internal.util.Clock; public class RoutingProcedureClusterCompositionProvider implements ClusterCompositionProvider { private static final String PROTOCOL_ERROR_MESSAGE = "Failed to parse '%s' result received from server due to "; diff --git a/driver/src/main/java/org/neo4j/driver/internal/cluster/RoutingTableRegistryImpl.java b/driver/src/main/java/org/neo4j/driver/internal/cluster/RoutingTableRegistryImpl.java index d0b059a1d0..75dee25982 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/cluster/RoutingTableRegistryImpl.java +++ b/driver/src/main/java/org/neo4j/driver/internal/cluster/RoutingTableRegistryImpl.java @@ -21,6 +21,7 @@ import static java.util.Objects.requireNonNull; import static org.neo4j.driver.internal.async.ConnectionContext.PENDING_DATABASE_NAME_EXCEPTION_SUPPLIER; +import java.time.Clock; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -39,7 +40,6 @@ import org.neo4j.driver.internal.DatabaseNameUtil; import org.neo4j.driver.internal.async.ConnectionContext; import org.neo4j.driver.internal.spi.ConnectionPool; -import org.neo4j.driver.internal.util.Clock; import org.neo4j.driver.internal.util.Futures; public class RoutingTableRegistryImpl implements RoutingTableRegistry { diff --git a/driver/src/main/java/org/neo4j/driver/internal/cluster/loadbalancing/LoadBalancer.java b/driver/src/main/java/org/neo4j/driver/internal/cluster/loadbalancing/LoadBalancer.java index f2687915f4..b452d6b0b8 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/cluster/loadbalancing/LoadBalancer.java +++ b/driver/src/main/java/org/neo4j/driver/internal/cluster/loadbalancing/LoadBalancer.java @@ -29,6 +29,7 @@ import static org.neo4j.driver.internal.util.Futures.onErrorContinue; import io.netty.util.concurrent.EventExecutorGroup; +import java.time.Clock; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CompletableFuture; @@ -50,7 +51,6 @@ import org.neo4j.driver.internal.spi.Connection; import org.neo4j.driver.internal.spi.ConnectionPool; import org.neo4j.driver.internal.spi.ConnectionProvider; -import org.neo4j.driver.internal.util.Clock; import org.neo4j.driver.internal.util.Futures; public class LoadBalancer implements ConnectionProvider { diff --git a/driver/src/main/java/org/neo4j/driver/internal/handlers/ChannelReleasingResetResponseHandler.java b/driver/src/main/java/org/neo4j/driver/internal/handlers/ChannelReleasingResetResponseHandler.java index d2e6a9378f..81fa978809 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/handlers/ChannelReleasingResetResponseHandler.java +++ b/driver/src/main/java/org/neo4j/driver/internal/handlers/ChannelReleasingResetResponseHandler.java @@ -23,11 +23,11 @@ import static org.neo4j.driver.internal.util.Futures.completedWithNull; import io.netty.channel.Channel; +import java.time.Clock; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; import org.neo4j.driver.internal.async.inbound.InboundMessageDispatcher; import org.neo4j.driver.internal.async.pool.ExtendedChannelPool; -import org.neo4j.driver.internal.util.Clock; public class ChannelReleasingResetResponseHandler extends ResetResponseHandler { private final Channel channel; diff --git a/driver/src/main/java/org/neo4j/driver/internal/metrics/InternalMetrics.java b/driver/src/main/java/org/neo4j/driver/internal/metrics/InternalMetrics.java index 266c0aa505..e92013e8ce 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/metrics/InternalMetrics.java +++ b/driver/src/main/java/org/neo4j/driver/internal/metrics/InternalMetrics.java @@ -21,6 +21,7 @@ import static java.lang.String.format; import static java.util.Collections.unmodifiableCollection; +import java.time.Clock; import java.util.Collection; import java.util.Map; import java.util.Objects; @@ -30,7 +31,6 @@ import org.neo4j.driver.Logger; import org.neo4j.driver.Logging; import org.neo4j.driver.Metrics; -import org.neo4j.driver.internal.util.Clock; import org.neo4j.driver.net.ServerAddress; final class InternalMetrics implements Metrics, MetricsListener { diff --git a/driver/src/main/java/org/neo4j/driver/internal/metrics/InternalMetricsProvider.java b/driver/src/main/java/org/neo4j/driver/internal/metrics/InternalMetricsProvider.java index 64204831f4..afbbc039d1 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/metrics/InternalMetricsProvider.java +++ b/driver/src/main/java/org/neo4j/driver/internal/metrics/InternalMetricsProvider.java @@ -18,9 +18,9 @@ */ package org.neo4j.driver.internal.metrics; +import java.time.Clock; import org.neo4j.driver.Logging; import org.neo4j.driver.Metrics; -import org.neo4j.driver.internal.util.Clock; public final class InternalMetricsProvider implements MetricsProvider { private final InternalMetrics metrics; diff --git a/driver/src/main/java/org/neo4j/driver/internal/metrics/TimeRecorderListenerEvent.java b/driver/src/main/java/org/neo4j/driver/internal/metrics/TimeRecorderListenerEvent.java index b7bd3c8e06..9194f1c6a8 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/metrics/TimeRecorderListenerEvent.java +++ b/driver/src/main/java/org/neo4j/driver/internal/metrics/TimeRecorderListenerEvent.java @@ -18,7 +18,7 @@ */ package org.neo4j.driver.internal.metrics; -import org.neo4j.driver.internal.util.Clock; +import java.time.Clock; final class TimeRecorderListenerEvent implements ListenerEvent { private final Clock clock; diff --git a/driver/src/main/java/org/neo4j/driver/internal/retry/ExponentialBackoffRetryLogic.java b/driver/src/main/java/org/neo4j/driver/internal/retry/ExponentialBackoffRetryLogic.java index f25bf8dac5..4f8d178dc0 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/retry/ExponentialBackoffRetryLogic.java +++ b/driver/src/main/java/org/neo4j/driver/internal/retry/ExponentialBackoffRetryLogic.java @@ -22,6 +22,7 @@ import io.netty.util.concurrent.EventExecutor; import io.netty.util.concurrent.EventExecutorGroup; +import java.time.Clock; import java.time.Duration; import java.util.ArrayList; import java.util.List; @@ -35,7 +36,6 @@ import org.neo4j.driver.exceptions.ClientException; import org.neo4j.driver.exceptions.Neo4jException; import org.neo4j.driver.exceptions.RetryableException; -import org.neo4j.driver.internal.util.Clock; import org.neo4j.driver.internal.util.Futures; import org.reactivestreams.Publisher; import reactor.core.publisher.Flux; @@ -58,10 +58,20 @@ public class ExponentialBackoffRetryLogic implements RetryLogic { private final double jitterFactor; private final EventExecutorGroup eventExecutorGroup; private final Clock clock; + private final SleepTask sleepTask; private final Logger log; public ExponentialBackoffRetryLogic( long maxTransactionRetryTime, EventExecutorGroup eventExecutorGroup, Clock clock, Logging logging) { + this(maxTransactionRetryTime, eventExecutorGroup, clock, logging, Thread::sleep); + } + + protected ExponentialBackoffRetryLogic( + long maxTransactionRetryTime, + EventExecutorGroup eventExecutorGroup, + Clock clock, + Logging logging, + SleepTask sleepTask) { this( maxTransactionRetryTime, INITIAL_RETRY_DELAY_MS, @@ -69,7 +79,8 @@ public ExponentialBackoffRetryLogic( RETRY_DELAY_JITTER_FACTOR, eventExecutorGroup, clock, - logging); + logging, + sleepTask); } ExponentialBackoffRetryLogic( @@ -79,13 +90,15 @@ public ExponentialBackoffRetryLogic( double jitterFactor, EventExecutorGroup eventExecutorGroup, Clock clock, - Logging logging) { + Logging logging, + SleepTask sleepTask) { this.maxRetryTimeMs = maxRetryTimeMs; this.initialRetryDelayMs = initialRetryDelayMs; this.multiplier = multiplier; this.jitterFactor = jitterFactor; this.eventExecutorGroup = eventExecutorGroup; this.clock = clock; + this.sleepTask = sleepTask; this.log = logging.getLog(getClass()); verifyAfterConstruction(); @@ -300,7 +313,7 @@ private long computeDelayWithJitter(long delayMs) { private void sleep(long delayMs) { try { - clock.sleep(delayMs); + sleepTask.sleep(delayMs); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new IllegalStateException("Retries interrupted", e); @@ -342,4 +355,9 @@ private static void addSuppressed(Throwable error, List suppressedErr } } } + + @FunctionalInterface + public interface SleepTask { + void sleep(long millis) throws InterruptedException; + } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/svm/MicrometerSubstitutions.java b/driver/src/main/java/org/neo4j/driver/internal/svm/MicrometerSubstitutions.java index 69e717c26d..d484c7ab43 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/svm/MicrometerSubstitutions.java +++ b/driver/src/main/java/org/neo4j/driver/internal/svm/MicrometerSubstitutions.java @@ -20,6 +20,7 @@ import com.oracle.svm.core.annotate.Substitute; import com.oracle.svm.core.annotate.TargetClass; +import java.time.Clock; import org.neo4j.driver.Config; import org.neo4j.driver.MetricsAdapter; import org.neo4j.driver.internal.DriverFactory; @@ -27,7 +28,6 @@ import org.neo4j.driver.internal.metrics.InternalMetricsProvider; import org.neo4j.driver.internal.metrics.MetricsProvider; import org.neo4j.driver.internal.metrics.MicrometerMetricsProvider; -import org.neo4j.driver.internal.util.Clock; @TargetClass(DriverFactory.class) final class Target_org_neo4j_driver_internal_DriverFactory { diff --git a/driver/src/main/java/org/neo4j/driver/internal/util/Clock.java b/driver/src/main/java/org/neo4j/driver/internal/util/Clock.java deleted file mode 100644 index 0e2b7b0cef..0000000000 --- a/driver/src/main/java/org/neo4j/driver/internal/util/Clock.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) "Neo4j" - * Neo4j Sweden AB [http://neo4j.com] - * - * This file is part of Neo4j. - * - * 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 org.neo4j.driver.internal.util; - -/** - * Since {@link java.time.Clock} is only available in Java 8, use our own until we drop java 7 support. - */ -public interface Clock { - /** Current time, in milliseconds. */ - long millis(); - - void sleep(long millis) throws InterruptedException; - - Clock SYSTEM = new Clock() { - @Override - public long millis() { - return System.currentTimeMillis(); - } - - @Override - public void sleep(long millis) throws InterruptedException { - Thread.sleep(millis); - } - }; -} diff --git a/driver/src/test/java/org/neo4j/driver/integration/ConnectionHandlingIT.java b/driver/src/test/java/org/neo4j/driver/integration/ConnectionHandlingIT.java index 713e639002..cc2e5c8155 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/ConnectionHandlingIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/ConnectionHandlingIT.java @@ -35,6 +35,7 @@ import static org.neo4j.driver.testutil.TestUtil.await; import io.netty.bootstrap.Bootstrap; +import java.time.Clock; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; @@ -68,7 +69,6 @@ import org.neo4j.driver.internal.security.SecurityPlanImpl; import org.neo4j.driver.internal.spi.Connection; import org.neo4j.driver.internal.spi.ConnectionPool; -import org.neo4j.driver.internal.util.Clock; import org.neo4j.driver.internal.util.EnabledOnNeo4jWith; import org.neo4j.driver.reactive.RxResult; import org.neo4j.driver.reactive.RxSession; diff --git a/driver/src/test/java/org/neo4j/driver/integration/ServerKilledIT.java b/driver/src/test/java/org/neo4j/driver/integration/ServerKilledIT.java index 7f847f104a..c8217b0f62 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/ServerKilledIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/ServerKilledIT.java @@ -22,6 +22,7 @@ import static org.junit.jupiter.api.Assertions.fail; import static org.neo4j.driver.Config.TrustStrategy.trustCustomCertificateSignedBy; +import java.time.Clock; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.stream.Stream; @@ -37,7 +38,6 @@ import org.neo4j.driver.exceptions.ServiceUnavailableException; import org.neo4j.driver.internal.DriverFactory; import org.neo4j.driver.internal.security.SecurityPlanImpl; -import org.neo4j.driver.internal.util.Clock; import org.neo4j.driver.internal.util.DriverFactoryWithClock; import org.neo4j.driver.internal.util.FakeClock; import org.neo4j.driver.testutil.DatabaseExtension; diff --git a/driver/src/test/java/org/neo4j/driver/integration/TransactionIT.java b/driver/src/test/java/org/neo4j/driver/integration/TransactionIT.java index c043e08901..1d3cfb4384 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/TransactionIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/TransactionIT.java @@ -31,6 +31,7 @@ import static org.neo4j.driver.testutil.TestUtil.assertNoCircularReferences; import io.netty.channel.Channel; +import java.time.Clock; import java.util.List; import java.util.Map; import java.util.function.Consumer; @@ -46,7 +47,6 @@ import org.neo4j.driver.exceptions.ClientException; import org.neo4j.driver.exceptions.ServiceUnavailableException; import org.neo4j.driver.internal.security.SecurityPlanImpl; -import org.neo4j.driver.internal.util.Clock; import org.neo4j.driver.internal.util.io.ChannelTrackingDriverFactory; import org.neo4j.driver.testutil.ParallelizableIT; import org.neo4j.driver.testutil.SessionExtension; @@ -346,7 +346,7 @@ void shouldBeResponsiveToThreadInterruptWhenWaitingForCommit() { @Test void shouldThrowWhenConnectionKilledDuringTransaction() { - ChannelTrackingDriverFactory factory = new ChannelTrackingDriverFactory(1, Clock.SYSTEM); + ChannelTrackingDriverFactory factory = new ChannelTrackingDriverFactory(1, Clock.systemUTC()); Config config = Config.builder().withLogging(DEV_NULL_LOGGING).build(); try (Driver driver = factory.newInstance( diff --git a/driver/src/test/java/org/neo4j/driver/integration/UnmanagedTransactionIT.java b/driver/src/test/java/org/neo4j/driver/integration/UnmanagedTransactionIT.java index 455794df31..ab857f88b1 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/UnmanagedTransactionIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/UnmanagedTransactionIT.java @@ -33,6 +33,7 @@ import io.netty.channel.ChannelPipeline; import io.netty.util.concurrent.Future; import java.io.IOException; +import java.time.Clock; import java.util.concurrent.CompletionStage; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -50,7 +51,6 @@ import org.neo4j.driver.internal.async.NetworkSession; import org.neo4j.driver.internal.async.UnmanagedTransaction; import org.neo4j.driver.internal.security.SecurityPlanImpl; -import org.neo4j.driver.internal.util.Clock; import org.neo4j.driver.internal.util.io.ChannelTrackingDriverFactory; import org.neo4j.driver.testutil.DatabaseExtension; import org.neo4j.driver.testutil.ParallelizableIT; @@ -195,7 +195,7 @@ private int countNodes(Object id) { } private void testCommitAndRollbackFailurePropagation(boolean commit) { - ChannelTrackingDriverFactory driverFactory = new ChannelTrackingDriverFactory(1, Clock.SYSTEM); + ChannelTrackingDriverFactory driverFactory = new ChannelTrackingDriverFactory(1, Clock.systemUTC()); Config config = Config.builder().withLogging(DEV_NULL_LOGGING).build(); try (Driver driver = driverFactory.newInstance( diff --git a/driver/src/test/java/org/neo4j/driver/internal/DriverFactoryTest.java b/driver/src/test/java/org/neo4j/driver/internal/DriverFactoryTest.java index 95205ce939..4b54793b11 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/DriverFactoryTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/DriverFactoryTest.java @@ -45,6 +45,7 @@ import io.netty.bootstrap.Bootstrap; import io.netty.util.concurrent.EventExecutorGroup; import java.net.URI; +import java.time.Clock; import java.util.function.Supplier; import java.util.stream.Stream; import org.junit.jupiter.api.Test; @@ -74,7 +75,6 @@ import org.neo4j.driver.internal.spi.Connection; import org.neo4j.driver.internal.spi.ConnectionPool; import org.neo4j.driver.internal.spi.ConnectionProvider; -import org.neo4j.driver.internal.util.Clock; class DriverFactoryTest { private static Stream testUris() { @@ -151,7 +151,7 @@ void shouldNotCreateDriverMetrics() { // Given Config config = Config.builder().withoutDriverMetrics().build(); // When - MetricsProvider provider = DriverFactory.getOrCreateMetricsProvider(config, Clock.SYSTEM); + MetricsProvider provider = DriverFactory.getOrCreateMetricsProvider(config, Clock.systemUTC()); // Then assertThat(provider, is(equalTo(DevNullMetricsProvider.INSTANCE))); } @@ -162,7 +162,7 @@ void shouldCreateDriverMetricsIfMonitoringEnabled() { Config config = Config.builder().withDriverMetrics().withLogging(Logging.none()).build(); // When - MetricsProvider provider = DriverFactory.getOrCreateMetricsProvider(config, Clock.SYSTEM); + MetricsProvider provider = DriverFactory.getOrCreateMetricsProvider(config, Clock.systemUTC()); // Then assertThat(provider instanceof InternalMetricsProvider, is(true)); } @@ -176,7 +176,7 @@ void shouldCreateMicrometerDriverMetricsIfMonitoringEnabled() { .withLogging(Logging.none()) .build(); // When - MetricsProvider provider = DriverFactory.getOrCreateMetricsProvider(config, Clock.SYSTEM); + MetricsProvider provider = DriverFactory.getOrCreateMetricsProvider(config, Clock.systemUTC()); // Then assertThat(provider instanceof MicrometerMetricsProvider, is(true)); } diff --git a/driver/src/test/java/org/neo4j/driver/internal/InternalDriverTest.java b/driver/src/test/java/org/neo4j/driver/internal/InternalDriverTest.java index d528e44fa2..b6805fd74d 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/InternalDriverTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/InternalDriverTest.java @@ -31,6 +31,7 @@ import static org.neo4j.driver.internal.util.Futures.failedFuture; import static org.neo4j.driver.testutil.TestUtil.await; +import java.time.Clock; import java.util.Collections; import java.util.concurrent.CompletableFuture; import org.junit.jupiter.api.Test; @@ -44,7 +45,6 @@ import org.neo4j.driver.internal.metrics.DevNullMetricsProvider; import org.neo4j.driver.internal.metrics.MetricsProvider; import org.neo4j.driver.internal.security.SecurityPlanImpl; -import org.neo4j.driver.internal.util.Clock; class InternalDriverTest { @Test @@ -154,7 +154,7 @@ private static InternalDriver newDriver(boolean isMetricsEnabled) { config = Config.builder().withDriverMetrics().build(); } - MetricsProvider metricsProvider = DriverFactory.getOrCreateMetricsProvider(config, Clock.SYSTEM); + MetricsProvider metricsProvider = DriverFactory.getOrCreateMetricsProvider(config, Clock.systemUTC()); return new InternalDriver( BookmarkManagers.defaultManager(BookmarkManagerConfig.builder().build()), SecurityPlanImpl.insecure(), diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/connection/NettyChannelInitializerTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/connection/NettyChannelInitializerTest.java index d00e967dbc..c9b8d99640 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/connection/NettyChannelInitializerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/connection/NettyChannelInitializerTest.java @@ -36,6 +36,7 @@ import io.netty.channel.embedded.EmbeddedChannel; import io.netty.handler.ssl.SslHandler; import java.security.GeneralSecurityException; +import java.time.Clock; import java.util.List; import javax.net.ssl.SNIHostName; import javax.net.ssl.SNIServerName; @@ -47,7 +48,6 @@ import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.security.SecurityPlan; import org.neo4j.driver.internal.security.SecurityPlanImpl; -import org.neo4j.driver.internal.util.Clock; import org.neo4j.driver.internal.util.FakeClock; class NettyChannelInitializerTest { @@ -108,8 +108,8 @@ void shouldUpdateChannelAttributes() { @Test void shouldIncludeSniHostName() throws Exception { BoltServerAddress address = new BoltServerAddress("database.neo4j.com", 8989); - NettyChannelInitializer initializer = - new NettyChannelInitializer(address, trustAllCertificates(), 10000, Clock.SYSTEM, DEV_NULL_LOGGING); + NettyChannelInitializer initializer = new NettyChannelInitializer( + address, trustAllCertificates(), 10000, Clock.systemUTC(), DEV_NULL_LOGGING); initializer.initChannel(channel); diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/pool/NettyChannelHealthCheckerTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/pool/NettyChannelHealthCheckerTest.java index 21c35851e8..a536cefe63 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/pool/NettyChannelHealthCheckerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/pool/NettyChannelHealthCheckerTest.java @@ -36,6 +36,7 @@ import io.netty.channel.Channel; import io.netty.channel.embedded.EmbeddedChannel; import io.netty.util.concurrent.Future; +import java.time.Clock; import java.util.Collections; import java.util.List; import java.util.Objects; @@ -48,7 +49,6 @@ import org.neo4j.driver.exceptions.AuthorizationExpiredException; import org.neo4j.driver.internal.async.inbound.InboundMessageDispatcher; import org.neo4j.driver.internal.messaging.request.ResetMessage; -import org.neo4j.driver.internal.util.Clock; class NettyChannelHealthCheckerTest { private final EmbeddedChannel channel = new EmbeddedChannel(); @@ -72,7 +72,7 @@ void shouldDropTooOldChannelsWhenMaxLifetimeEnabled() { DEFAULT_CONNECTION_ACQUISITION_TIMEOUT, maxLifetime, DEFAULT_IDLE_TIME_BEFORE_CONNECTION_TEST); - Clock clock = Clock.SYSTEM; + Clock clock = Clock.systemUTC(); NettyChannelHealthChecker healthChecker = newHealthChecker(settings, clock); setCreationTimestamp(channel, clock.millis() - maxLifetime * 2); @@ -88,7 +88,7 @@ void shouldAllowVeryOldChannelsWhenMaxLifetimeDisabled() { DEFAULT_CONNECTION_ACQUISITION_TIMEOUT, NOT_CONFIGURED, DEFAULT_IDLE_TIME_BEFORE_CONNECTION_TEST); - NettyChannelHealthChecker healthChecker = newHealthChecker(settings, Clock.SYSTEM); + NettyChannelHealthChecker healthChecker = newHealthChecker(settings, Clock.systemUTC()); setCreationTimestamp(channel, 0); Future healthy = healthChecker.isHealthy(channel); @@ -103,7 +103,7 @@ void shouldFailAllConnectionsCreatedOnOrBeforeExpirationTimestamp() { DEFAULT_CONNECTION_ACQUISITION_TIMEOUT, NOT_CONFIGURED, DEFAULT_IDLE_TIME_BEFORE_CONNECTION_TEST); - Clock clock = Clock.SYSTEM; + Clock clock = Clock.systemUTC(); NettyChannelHealthChecker healthChecker = newHealthChecker(settings, clock); long initialTimestamp = clock.millis(); @@ -134,7 +134,7 @@ void shouldUseGreatestExpirationTimestamp() { DEFAULT_CONNECTION_ACQUISITION_TIMEOUT, NOT_CONFIGURED, DEFAULT_IDLE_TIME_BEFORE_CONNECTION_TEST); - Clock clock = Clock.SYSTEM; + Clock clock = Clock.systemUTC(); NettyChannelHealthChecker healthChecker = newHealthChecker(settings, clock); long initialTimestamp = clock.millis(); @@ -177,7 +177,7 @@ private void testPing(boolean resetMessageSuccessful) { DEFAULT_CONNECTION_ACQUISITION_TIMEOUT, NOT_CONFIGURED, idleTimeBeforeConnectionTest); - Clock clock = Clock.SYSTEM; + Clock clock = Clock.systemUTC(); NettyChannelHealthChecker healthChecker = newHealthChecker(settings, clock); setCreationTimestamp(channel, clock.millis()); @@ -203,7 +203,7 @@ private void testActiveConnectionCheck(boolean channelActive) { DEFAULT_CONNECTION_ACQUISITION_TIMEOUT, NOT_CONFIGURED, DEFAULT_IDLE_TIME_BEFORE_CONNECTION_TEST); - Clock clock = Clock.SYSTEM; + Clock clock = Clock.systemUTC(); NettyChannelHealthChecker healthChecker = newHealthChecker(settings, clock); setCreationTimestamp(channel, clock.millis()); diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/pool/TestConnectionPool.java b/driver/src/test/java/org/neo4j/driver/internal/async/pool/TestConnectionPool.java index 1bdda1c37f..2ecab71a37 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/pool/TestConnectionPool.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/pool/TestConnectionPool.java @@ -28,6 +28,7 @@ import io.netty.bootstrap.Bootstrap; import io.netty.channel.Channel; import io.netty.channel.embedded.EmbeddedChannel; +import java.time.Clock; import java.util.HashMap; import java.util.Map; import java.util.concurrent.CompletionStage; @@ -38,7 +39,6 @@ import org.neo4j.driver.internal.metrics.ListenerEvent; import org.neo4j.driver.internal.metrics.MetricsListener; import org.neo4j.driver.internal.spi.Connection; -import org.neo4j.driver.internal.util.Clock; public class TestConnectionPool extends ConnectionPoolImpl { final Map channelPoolsByAddress = new HashMap<>(); diff --git a/driver/src/test/java/org/neo4j/driver/internal/cluster/ClusterRoutingTableTest.java b/driver/src/test/java/org/neo4j/driver/internal/cluster/ClusterRoutingTableTest.java index 3ef5dd8e9b..89304ef852 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/cluster/ClusterRoutingTableTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/cluster/ClusterRoutingTableTest.java @@ -37,13 +37,13 @@ import static org.neo4j.driver.internal.util.ClusterCompositionUtil.F; import static org.neo4j.driver.internal.util.ClusterCompositionUtil.createClusterComposition; +import java.time.Clock; import java.time.Duration; import java.util.List; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; import org.neo4j.driver.internal.BoltServerAddress; -import org.neo4j.driver.internal.util.Clock; import org.neo4j.driver.internal.util.FakeClock; class ClusterRoutingTableTest { @@ -205,13 +205,13 @@ void shouldTreatOneRouterAsValid() { @Test void shouldHaveBeStaleForExpiredTime() throws Throwable { - ClusterRoutingTable routingTable = newRoutingTable(Clock.SYSTEM); + ClusterRoutingTable routingTable = newRoutingTable(Clock.systemUTC()); assertTrue(routingTable.hasBeenStaleFor(0)); } @Test void shouldNotHaveBeStaleForUnexpiredTime() throws Throwable { - ClusterRoutingTable routingTable = newRoutingTable(Clock.SYSTEM); + ClusterRoutingTable routingTable = newRoutingTable(Clock.systemUTC()); assertFalse(routingTable.hasBeenStaleFor(Duration.ofSeconds(30).toMillis())); } diff --git a/driver/src/test/java/org/neo4j/driver/internal/cluster/RoutingProcedureClusterCompositionProviderTest.java b/driver/src/test/java/org/neo4j/driver/internal/cluster/RoutingProcedureClusterCompositionProviderTest.java index 3f57adc494..81968ce86e 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/cluster/RoutingProcedureClusterCompositionProviderTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/cluster/RoutingProcedureClusterCompositionProviderTest.java @@ -35,6 +35,7 @@ import static org.neo4j.driver.internal.util.Futures.failedFuture; import static org.neo4j.driver.testutil.TestUtil.await; +import java.time.Clock; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -53,7 +54,6 @@ import org.neo4j.driver.internal.messaging.v4.BoltProtocolV4; import org.neo4j.driver.internal.messaging.v43.BoltProtocolV43; import org.neo4j.driver.internal.spi.Connection; -import org.neo4j.driver.internal.util.Clock; import org.neo4j.driver.internal.value.StringValue; class RoutingProcedureClusterCompositionProviderTest { diff --git a/driver/src/test/java/org/neo4j/driver/internal/cluster/RoutingTableRegistryImplTest.java b/driver/src/test/java/org/neo4j/driver/internal/cluster/RoutingTableRegistryImplTest.java index 9159273292..538b198516 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/cluster/RoutingTableRegistryImplTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/cluster/RoutingTableRegistryImplTest.java @@ -45,6 +45,7 @@ import static org.neo4j.driver.internal.util.ClusterCompositionUtil.F; import static org.neo4j.driver.testutil.TestUtil.await; +import java.time.Clock; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; @@ -61,12 +62,11 @@ import org.neo4j.driver.internal.async.ImmutableConnectionContext; import org.neo4j.driver.internal.cluster.RoutingTableRegistryImpl.RoutingTableHandlerFactory; import org.neo4j.driver.internal.spi.ConnectionPool; -import org.neo4j.driver.internal.util.Clock; class RoutingTableRegistryImplTest { @Test void factoryShouldCreateARoutingTableWithSameDatabaseName() { - Clock clock = Clock.SYSTEM; + Clock clock = Clock.systemUTC(); RoutingTableHandlerFactory factory = new RoutingTableHandlerFactory( mock(ConnectionPool.class), mock(RediscoveryImpl.class), diff --git a/driver/src/test/java/org/neo4j/driver/internal/cluster/loadbalancing/RoutingTableAndConnectionPoolTest.java b/driver/src/test/java/org/neo4j/driver/internal/cluster/loadbalancing/RoutingTableAndConnectionPoolTest.java index 7971c9ff99..07f152f71f 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/cluster/loadbalancing/RoutingTableAndConnectionPoolTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/cluster/loadbalancing/RoutingTableAndConnectionPoolTest.java @@ -36,6 +36,7 @@ import io.netty.bootstrap.Bootstrap; import io.netty.util.concurrent.GlobalEventExecutor; +import java.time.Clock; import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; @@ -75,7 +76,6 @@ import org.neo4j.driver.internal.metrics.MetricsListener; import org.neo4j.driver.internal.spi.Connection; import org.neo4j.driver.internal.spi.ConnectionPool; -import org.neo4j.driver.internal.util.Clock; import org.neo4j.driver.internal.util.Futures; class RoutingTableAndConnectionPoolTest { @@ -91,7 +91,7 @@ class RoutingTableAndConnectionPoolTest { private static final String[] DATABASES = new String[] {"", SYSTEM_DATABASE_NAME, "my database"}; private final Random random = new Random(); - private final Clock clock = Clock.SYSTEM; + private final Clock clock = Clock.systemUTC(); private final Logging logging = none(); @Test diff --git a/driver/src/test/java/org/neo4j/driver/internal/handlers/ChannelReleasingResetResponseHandlerTest.java b/driver/src/test/java/org/neo4j/driver/internal/handlers/ChannelReleasingResetResponseHandlerTest.java index c118a24baa..98324cdd7f 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/handlers/ChannelReleasingResetResponseHandlerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/handlers/ChannelReleasingResetResponseHandlerTest.java @@ -31,12 +31,12 @@ import static org.neo4j.driver.internal.util.Futures.completedWithNull; import io.netty.channel.embedded.EmbeddedChannel; +import java.time.Clock; import java.util.concurrent.CompletableFuture; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.neo4j.driver.internal.async.inbound.InboundMessageDispatcher; import org.neo4j.driver.internal.async.pool.ExtendedChannelPool; -import org.neo4j.driver.internal.util.Clock; import org.neo4j.driver.internal.util.FakeClock; class ChannelReleasingResetResponseHandlerTest { diff --git a/driver/src/test/java/org/neo4j/driver/internal/retry/ExponentialBackoffRetryLogicTest.java b/driver/src/test/java/org/neo4j/driver/internal/retry/ExponentialBackoffRetryLogicTest.java index becfec09f1..7ddfae9114 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/retry/ExponentialBackoffRetryLogicTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/retry/ExponentialBackoffRetryLogicTest.java @@ -47,6 +47,7 @@ import static org.neo4j.driver.internal.util.Futures.failedFuture; import static org.neo4j.driver.testutil.TestUtil.await; +import java.time.Clock; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; @@ -71,7 +72,6 @@ import org.neo4j.driver.exceptions.ServiceUnavailableException; import org.neo4j.driver.exceptions.SessionExpiredException; import org.neo4j.driver.exceptions.TransientException; -import org.neo4j.driver.internal.util.Clock; import org.neo4j.driver.internal.util.ImmediateSchedulingEventExecutor; import org.reactivestreams.Publisher; import reactor.core.publisher.Flux; @@ -84,40 +84,41 @@ class ExponentialBackoffRetryLogicTest { @Test void throwsForIllegalMaxRetryTime() { - IllegalArgumentException error = - assertThrows(IllegalArgumentException.class, () -> newRetryLogic(-100, 1, 1, 1, Clock.SYSTEM)); + IllegalArgumentException error = assertThrows( + IllegalArgumentException.class, () -> newRetryLogic(-100, 1, 1, 1, Clock.systemUTC(), (ignored) -> {})); assertThat(error.getMessage(), containsString("Max retry time")); } @Test void throwsForIllegalInitialRetryDelay() { - IllegalArgumentException error = - assertThrows(IllegalArgumentException.class, () -> newRetryLogic(1, -100, 1, 1, Clock.SYSTEM)); + IllegalArgumentException error = assertThrows( + IllegalArgumentException.class, () -> newRetryLogic(1, -100, 1, 1, Clock.systemUTC(), (ignored) -> {})); assertThat(error.getMessage(), containsString("Initial retry delay")); } @Test void throwsForIllegalMultiplier() { - IllegalArgumentException error = - assertThrows(IllegalArgumentException.class, () -> newRetryLogic(1, 1, 0.42, 1, Clock.SYSTEM)); + IllegalArgumentException error = assertThrows( + IllegalArgumentException.class, () -> newRetryLogic(1, 1, 0.42, 1, Clock.systemUTC(), (ignored) -> {})); assertThat(error.getMessage(), containsString("Multiplier")); } @Test void throwsForIllegalJitterFactor() { - IllegalArgumentException error1 = - assertThrows(IllegalArgumentException.class, () -> newRetryLogic(1, 1, 1, -0.42, Clock.SYSTEM)); + IllegalArgumentException error1 = assertThrows( + IllegalArgumentException.class, + () -> newRetryLogic(1, 1, 1, -0.42, Clock.systemUTC(), (ignored) -> {})); assertThat(error1.getMessage(), containsString("Jitter")); - IllegalArgumentException error2 = - assertThrows(IllegalArgumentException.class, () -> newRetryLogic(1, 1, 1, 1.42, Clock.SYSTEM)); + IllegalArgumentException error2 = assertThrows( + IllegalArgumentException.class, () -> newRetryLogic(1, 1, 1, 1.42, Clock.systemUTC(), (ignored) -> {})); assertThat(error2.getMessage(), containsString("Jitter")); } @Test void throwsForIllegalClock() { IllegalArgumentException error = - assertThrows(IllegalArgumentException.class, () -> newRetryLogic(1, 1, 1, 1, null)); + assertThrows(IllegalArgumentException.class, () -> newRetryLogic(1, 1, 1, 1, null, (ignored) -> {})); assertThat(error.getMessage(), containsString("Clock")); } @@ -128,11 +129,13 @@ void nextDelayCalculatedAccordingToMultiplier() throws Exception { int multiplier = 3; int noJitter = 0; Clock clock = mock(Clock.class); - ExponentialBackoffRetryLogic logic = newRetryLogic(MAX_VALUE, initialDelay, multiplier, noJitter, clock); + var sleepTask = mock(ExponentialBackoffRetryLogic.SleepTask.class); + ExponentialBackoffRetryLogic logic = + newRetryLogic(MAX_VALUE, initialDelay, multiplier, noJitter, clock, sleepTask); retry(logic, retries); - assertEquals(delaysWithoutJitter(initialDelay, multiplier, retries), sleepValues(clock, retries)); + assertEquals(delaysWithoutJitter(initialDelay, multiplier, retries), sleepValues(sleepTask, retries)); } @Test @@ -144,7 +147,7 @@ void nextDelayCalculatedAccordingToMultiplierAsync() { int noJitter = 0; ExponentialBackoffRetryLogic retryLogic = - newRetryLogic(MAX_VALUE, initialDelay, multiplier, noJitter, Clock.SYSTEM); + newRetryLogic(MAX_VALUE, initialDelay, multiplier, noJitter, Clock.systemUTC(), (ignored) -> {}); CompletionStage future = retryAsync(retryLogic, retries, result); @@ -161,7 +164,7 @@ void nextDelayCalculatedAccordingToMultiplierRx() { int noJitter = 0; ExponentialBackoffRetryLogic retryLogic = - newRetryLogic(MAX_VALUE, initialDelay, multiplier, noJitter, Clock.SYSTEM); + newRetryLogic(MAX_VALUE, initialDelay, multiplier, noJitter, Clock.systemUTC(), (ignored) -> {}); Mono single = Flux.from(retryRx(retryLogic, retries, result)).single(); @@ -176,12 +179,13 @@ void nextDelayCalculatedAccordingToJitter() throws Exception { int initialDelay = 1; int multiplier = 2; Clock clock = mock(Clock.class); - - ExponentialBackoffRetryLogic logic = newRetryLogic(MAX_VALUE, initialDelay, multiplier, jitterFactor, clock); + var sleepTask = mock(ExponentialBackoffRetryLogic.SleepTask.class); + ExponentialBackoffRetryLogic logic = + newRetryLogic(MAX_VALUE, initialDelay, multiplier, jitterFactor, clock, sleepTask); retry(logic, retries); - List sleepValues = sleepValues(clock, retries); + List sleepValues = sleepValues(sleepTask, retries); List delaysWithoutJitter = delaysWithoutJitter(initialDelay, multiplier, retries); assertDelaysApproximatelyEqual(delaysWithoutJitter, sleepValues, jitterFactor); @@ -196,7 +200,7 @@ void nextDelayCalculatedAccordingToJitterAsync() { int multiplier = 2; ExponentialBackoffRetryLogic retryLogic = - newRetryLogic(MAX_VALUE, initialDelay, multiplier, jitterFactor, mock(Clock.class)); + newRetryLogic(MAX_VALUE, initialDelay, multiplier, jitterFactor, mock(Clock.class), (ignored) -> {}); CompletionStage future = retryAsync(retryLogic, retries, result); assertEquals(result, await(future)); @@ -216,7 +220,7 @@ void nextDelayCalculatedAccordingToJitterRx() { int multiplier = 2; ExponentialBackoffRetryLogic retryLogic = - newRetryLogic(MAX_VALUE, initialDelay, multiplier, jitterFactor, mock(Clock.class)); + newRetryLogic(MAX_VALUE, initialDelay, multiplier, jitterFactor, mock(Clock.class), (ignored) -> {}); Mono single = Flux.from(retryRx(retryLogic, retries, result)).single(); assertEquals(result, await(single)); @@ -229,17 +233,19 @@ void nextDelayCalculatedAccordingToJitterRx() { @Test void doesNotRetryWhenMaxRetryTimeExceeded() throws Exception { - long retryStart = Clock.SYSTEM.millis(); + long retryStart = Clock.systemUTC().millis(); int initialDelay = 100; int multiplier = 2; long maxRetryTimeMs = 45; Clock clock = mock(Clock.class); + var sleepTask = mock(ExponentialBackoffRetryLogic.SleepTask.class); when(clock.millis()) .thenReturn(retryStart) .thenReturn(retryStart + maxRetryTimeMs - 5) .thenReturn(retryStart + maxRetryTimeMs + 7); - ExponentialBackoffRetryLogic logic = newRetryLogic(maxRetryTimeMs, initialDelay, multiplier, 0, clock); + ExponentialBackoffRetryLogic logic = + newRetryLogic(maxRetryTimeMs, initialDelay, multiplier, 0, clock, sleepTask); Supplier workMock = newWorkMock(); SessionExpiredException error = sessionExpired(); @@ -248,14 +254,14 @@ void doesNotRetryWhenMaxRetryTimeExceeded() throws Exception { Exception e = assertThrows(Exception.class, () -> logic.retry(workMock)); assertEquals(error, e); - verify(clock).sleep(initialDelay); - verify(clock).sleep(initialDelay * multiplier); + verify(sleepTask).sleep(initialDelay); + verify(sleepTask).sleep(initialDelay * multiplier); verify(workMock, times(3)).get(); } @Test void doesNotRetryWhenMaxRetryTimeExceededAsync() { - long retryStart = Clock.SYSTEM.millis(); + long retryStart = Clock.systemUTC().millis(); int initialDelay = 100; int multiplier = 2; long maxRetryTimeMs = 45; @@ -265,7 +271,8 @@ void doesNotRetryWhenMaxRetryTimeExceededAsync() { .thenReturn(retryStart + maxRetryTimeMs - 5) .thenReturn(retryStart + maxRetryTimeMs + 7); - ExponentialBackoffRetryLogic retryLogic = newRetryLogic(maxRetryTimeMs, initialDelay, multiplier, 0, clock); + ExponentialBackoffRetryLogic retryLogic = + newRetryLogic(maxRetryTimeMs, initialDelay, multiplier, 0, clock, (ignored) -> {}); Supplier> workMock = newWorkMock(); SessionExpiredException error = sessionExpired(); @@ -286,7 +293,7 @@ void doesNotRetryWhenMaxRetryTimeExceededAsync() { @Test void doesNotRetryWhenMaxRetryTimeExceededRx() { - long retryStart = Clock.SYSTEM.millis(); + long retryStart = Clock.systemUTC().millis(); int initialDelay = 100; int multiplier = 2; long maxRetryTimeMs = 45; @@ -296,7 +303,8 @@ void doesNotRetryWhenMaxRetryTimeExceededRx() { .thenReturn(retryStart + maxRetryTimeMs - 5) .thenReturn(retryStart + maxRetryTimeMs + 7); - ExponentialBackoffRetryLogic retryLogic = newRetryLogic(maxRetryTimeMs, initialDelay, multiplier, 0, clock); + ExponentialBackoffRetryLogic retryLogic = + newRetryLogic(maxRetryTimeMs, initialDelay, multiplier, 0, clock, (ignored) -> {}); SessionExpiredException error = sessionExpired(); AtomicInteger executionCount = new AtomicInteger(); @@ -317,7 +325,8 @@ void doesNotRetryWhenMaxRetryTimeExceededRx() { @Test void sleepsOnServiceUnavailableException() throws Exception { Clock clock = mock(Clock.class); - ExponentialBackoffRetryLogic logic = newRetryLogic(1, 42, 1, 0, clock); + var sleepTask = mock(ExponentialBackoffRetryLogic.SleepTask.class); + ExponentialBackoffRetryLogic logic = newRetryLogic(1, 42, 1, 0, clock, sleepTask); Supplier workMock = newWorkMock(); ServiceUnavailableException error = serviceUnavailable(); @@ -326,7 +335,7 @@ void sleepsOnServiceUnavailableException() throws Exception { assertNull(logic.retry(workMock)); verify(workMock, times(2)).get(); - verify(clock).sleep(42); + verify(sleepTask).sleep(42); } @Test @@ -334,7 +343,7 @@ void schedulesRetryOnServiceUnavailableExceptionAsync() { String result = "The Result"; Clock clock = mock(Clock.class); - ExponentialBackoffRetryLogic retryLogic = newRetryLogic(1, 42, 1, 0, clock); + ExponentialBackoffRetryLogic retryLogic = newRetryLogic(1, 42, 1, 0, clock, (ignored) -> {}); Supplier> workMock = newWorkMock(); ServiceUnavailableException error = serviceUnavailable(); @@ -351,7 +360,8 @@ void schedulesRetryOnServiceUnavailableExceptionAsync() { @Test void sleepsOnSessionExpiredException() throws Exception { Clock clock = mock(Clock.class); - ExponentialBackoffRetryLogic logic = newRetryLogic(1, 4242, 1, 0, clock); + var sleepTask = mock(ExponentialBackoffRetryLogic.SleepTask.class); + ExponentialBackoffRetryLogic logic = newRetryLogic(1, 4242, 1, 0, clock, sleepTask); Supplier workMock = newWorkMock(); SessionExpiredException error = sessionExpired(); @@ -360,7 +370,7 @@ void sleepsOnSessionExpiredException() throws Exception { assertNull(logic.retry(workMock)); verify(workMock, times(2)).get(); - verify(clock).sleep(4242); + verify(sleepTask).sleep(4242); } @Test @@ -368,7 +378,7 @@ void schedulesRetryOnSessionExpiredExceptionAsync() { String result = "The Result"; Clock clock = mock(Clock.class); - ExponentialBackoffRetryLogic retryLogic = newRetryLogic(1, 4242, 1, 0, clock); + ExponentialBackoffRetryLogic retryLogic = newRetryLogic(1, 4242, 1, 0, clock, (ignored) -> {}); Supplier> workMock = newWorkMock(); SessionExpiredException error = sessionExpired(); @@ -385,7 +395,8 @@ void schedulesRetryOnSessionExpiredExceptionAsync() { @Test void sleepsOnTransientException() throws Exception { Clock clock = mock(Clock.class); - ExponentialBackoffRetryLogic logic = newRetryLogic(1, 23, 1, 0, clock); + var sleepTask = mock(ExponentialBackoffRetryLogic.SleepTask.class); + ExponentialBackoffRetryLogic logic = newRetryLogic(1, 23, 1, 0, clock, sleepTask); Supplier workMock = newWorkMock(); TransientException error = transientException(); @@ -394,7 +405,7 @@ void sleepsOnTransientException() throws Exception { assertNull(logic.retry(workMock)); verify(workMock, times(2)).get(); - verify(clock).sleep(23); + verify(sleepTask).sleep(23); } @Test @@ -402,7 +413,7 @@ void schedulesRetryOnTransientExceptionAsync() { String result = "The Result"; Clock clock = mock(Clock.class); - ExponentialBackoffRetryLogic retryLogic = newRetryLogic(1, 23, 1, 0, clock); + ExponentialBackoffRetryLogic retryLogic = newRetryLogic(1, 23, 1, 0, clock, (ignored) -> {}); Supplier> workMock = newWorkMock(); TransientException error = transientException(); @@ -419,7 +430,8 @@ void schedulesRetryOnTransientExceptionAsync() { @Test void throwsWhenUnknownError() throws Exception { Clock clock = mock(Clock.class); - ExponentialBackoffRetryLogic logic = newRetryLogic(1, 1, 1, 1, clock); + var sleepTask = mock(ExponentialBackoffRetryLogic.SleepTask.class); + ExponentialBackoffRetryLogic logic = newRetryLogic(1, 1, 1, 1, clock, sleepTask); Supplier workMock = newWorkMock(); IllegalStateException error = new IllegalStateException(); @@ -429,14 +441,13 @@ void throwsWhenUnknownError() throws Exception { assertEquals(error, e); verify(workMock).get(); - verify(clock, never()).sleep(anyLong()); + verify(sleepTask, never()).sleep(anyLong()); } @Test void doesNotRetryOnUnknownErrorAsync() { Clock clock = mock(Clock.class); - - ExponentialBackoffRetryLogic retryLogic = newRetryLogic(1, 1, 1, 1, clock); + ExponentialBackoffRetryLogic retryLogic = newRetryLogic(1, 1, 1, 1, clock, (ignored) -> {}); Supplier> workMock = newWorkMock(); IllegalStateException error = new IllegalStateException(); @@ -452,7 +463,8 @@ void doesNotRetryOnUnknownErrorAsync() { @Test void throwsWhenTransactionTerminatedError() throws Exception { Clock clock = mock(Clock.class); - ExponentialBackoffRetryLogic logic = newRetryLogic(1, 13, 1, 0, clock); + var sleepTask = mock(ExponentialBackoffRetryLogic.SleepTask.class); + ExponentialBackoffRetryLogic logic = newRetryLogic(1, 13, 1, 0, clock, sleepTask); Supplier workMock = newWorkMock(); ClientException error = new ClientException("Neo.ClientError.Transaction.Terminated", ""); @@ -462,14 +474,13 @@ void throwsWhenTransactionTerminatedError() throws Exception { assertEquals(error, e); verify(workMock).get(); - verify(clock, never()).sleep(13); + verify(sleepTask, never()).sleep(13); } @Test void doesNotRetryOnTransactionTerminatedErrorAsync() { Clock clock = mock(Clock.class); - - ExponentialBackoffRetryLogic retryLogic = newRetryLogic(1, 13, 1, 0, clock); + ExponentialBackoffRetryLogic retryLogic = newRetryLogic(1, 13, 1, 0, clock, (ignored) -> {}); Supplier> workMock = newWorkMock(); ClientException error = new ClientException("Neo.ClientError.Transaction.Terminated", ""); @@ -485,7 +496,8 @@ void doesNotRetryOnTransactionTerminatedErrorAsync() { @Test void throwsWhenTransactionLockClientStoppedError() throws Exception { Clock clock = mock(Clock.class); - ExponentialBackoffRetryLogic logic = newRetryLogic(1, 13, 1, 0, clock); + var sleepTask = mock(ExponentialBackoffRetryLogic.SleepTask.class); + ExponentialBackoffRetryLogic logic = newRetryLogic(1, 13, 1, 0, clock, sleepTask); Supplier workMock = newWorkMock(); ClientException error = new ClientException("Neo.ClientError.Transaction.LockClientStopped", ""); @@ -495,14 +507,13 @@ void throwsWhenTransactionLockClientStoppedError() throws Exception { assertEquals(error, e); verify(workMock).get(); - verify(clock, never()).sleep(13); + verify(sleepTask, never()).sleep(13); } @Test void doesNotRetryOnTransactionLockClientStoppedErrorAsync() { Clock clock = mock(Clock.class); - - ExponentialBackoffRetryLogic retryLogic = newRetryLogic(1, 15, 1, 0, clock); + ExponentialBackoffRetryLogic retryLogic = newRetryLogic(1, 15, 1, 0, clock, (ignored) -> {}); Supplier> workMock = newWorkMock(); ClientException error = new ClientException("Neo.ClientError.Transaction.LockClientStopped", ""); @@ -520,8 +531,7 @@ void doesNotRetryOnTransactionLockClientStoppedErrorAsync() { void schedulesRetryOnErrorRx(Exception error) { String result = "The Result"; Clock clock = mock(Clock.class); - - ExponentialBackoffRetryLogic retryLogic = newRetryLogic(1, 4242, 1, 0, clock); + ExponentialBackoffRetryLogic retryLogic = newRetryLogic(1, 4242, 1, 0, clock, (ignored) -> {}); Publisher publisher = createMono(result, error); Mono single = Flux.from(retryLogic.retryRx(publisher)).single(); @@ -537,7 +547,7 @@ void schedulesRetryOnErrorRx(Exception error) { @MethodSource("cannotBeRetriedErrors") void scheduleNoRetryOnErrorRx(Exception error) { Clock clock = mock(Clock.class); - ExponentialBackoffRetryLogic retryLogic = newRetryLogic(1, 10, 1, 1, clock); + ExponentialBackoffRetryLogic retryLogic = newRetryLogic(1, 10, 1, 1, clock, (ignored) -> {}); Mono single = Flux.from(retryLogic.retryRx(Mono.error(error))).single(); @@ -550,8 +560,9 @@ void scheduleNoRetryOnErrorRx(Exception error) { @Test void throwsWhenSleepInterrupted() throws Exception { Clock clock = mock(Clock.class); - doThrow(new InterruptedException()).when(clock).sleep(1); - ExponentialBackoffRetryLogic logic = newRetryLogic(1, 1, 1, 0, clock); + var sleepTask = mock(ExponentialBackoffRetryLogic.SleepTask.class); + doThrow(new InterruptedException()).when(sleepTask).sleep(1); + ExponentialBackoffRetryLogic logic = newRetryLogic(1, 1, 1, 0, clock, sleepTask); Supplier workMock = newWorkMock(); when(workMock.get()).thenThrow(serviceUnavailable()); @@ -572,7 +583,8 @@ void collectsSuppressedErrors() throws Exception { int multiplier = 2; Clock clock = mock(Clock.class); when(clock.millis()).thenReturn(0L).thenReturn(10L).thenReturn(15L).thenReturn(25L); - ExponentialBackoffRetryLogic logic = newRetryLogic(maxRetryTime, initialDelay, multiplier, 0, clock); + var sleepTask = mock(ExponentialBackoffRetryLogic.SleepTask.class); + ExponentialBackoffRetryLogic logic = newRetryLogic(maxRetryTime, initialDelay, multiplier, 0, clock, sleepTask); Supplier workMock = newWorkMock(); SessionExpiredException error1 = sessionExpired(); @@ -591,10 +603,10 @@ void collectsSuppressedErrors() throws Exception { verify(workMock, times(4)).get(); - verify(clock, times(3)).sleep(anyLong()); - verify(clock).sleep(initialDelay); - verify(clock).sleep(initialDelay * multiplier); - verify(clock).sleep(initialDelay * multiplier * multiplier); + verify(sleepTask, times(3)).sleep(anyLong()); + verify(sleepTask).sleep(initialDelay); + verify(sleepTask).sleep(initialDelay * multiplier); + verify(sleepTask).sleep(initialDelay * multiplier * multiplier); } @Test @@ -606,7 +618,8 @@ void collectsSuppressedErrorsAsync() { Clock clock = mock(Clock.class); when(clock.millis()).thenReturn(0L).thenReturn(10L).thenReturn(15L).thenReturn(25L); - ExponentialBackoffRetryLogic retryLogic = newRetryLogic(maxRetryTime, initialDelay, multiplier, 0, clock); + ExponentialBackoffRetryLogic retryLogic = + newRetryLogic(maxRetryTime, initialDelay, multiplier, 0, clock, (ignored) -> {}); Supplier> workMock = newWorkMock(); SessionExpiredException error1 = sessionExpired(); @@ -640,13 +653,14 @@ void collectsSuppressedErrorsAsync() { } @Test - void collectsSuppressedErrorsRx() throws Exception { + void collectsSuppressedErrorsRx() { long maxRetryTime = 20; int initialDelay = 15; int multiplier = 2; Clock clock = mock(Clock.class); when(clock.millis()).thenReturn(0L).thenReturn(10L).thenReturn(15L).thenReturn(25L); - ExponentialBackoffRetryLogic logic = newRetryLogic(maxRetryTime, initialDelay, multiplier, 0, clock); + ExponentialBackoffRetryLogic logic = + newRetryLogic(maxRetryTime, initialDelay, multiplier, 0, clock, (ignored) -> {}); SessionExpiredException error1 = sessionExpired(); SessionExpiredException error2 = sessionExpired(); @@ -680,7 +694,8 @@ void doesNotCollectSuppressedErrorsWhenSameErrorIsThrown() throws Exception { int multiplier = 2; Clock clock = mock(Clock.class); when(clock.millis()).thenReturn(0L).thenReturn(10L).thenReturn(25L); - ExponentialBackoffRetryLogic logic = newRetryLogic(maxRetryTime, initialDelay, multiplier, 0, clock); + var sleepTask = mock(ExponentialBackoffRetryLogic.SleepTask.class); + ExponentialBackoffRetryLogic logic = newRetryLogic(maxRetryTime, initialDelay, multiplier, 0, clock, sleepTask); Supplier workMock = newWorkMock(); SessionExpiredException error = sessionExpired(); @@ -692,9 +707,9 @@ void doesNotCollectSuppressedErrorsWhenSameErrorIsThrown() throws Exception { verify(workMock, times(3)).get(); - verify(clock, times(2)).sleep(anyLong()); - verify(clock).sleep(initialDelay); - verify(clock).sleep(initialDelay * multiplier); + verify(sleepTask, times(2)).sleep(anyLong()); + verify(sleepTask).sleep(initialDelay); + verify(sleepTask).sleep(initialDelay * multiplier); } @Test @@ -705,7 +720,8 @@ void doesNotCollectSuppressedErrorsWhenSameErrorIsThrownAsync() { Clock clock = mock(Clock.class); when(clock.millis()).thenReturn(0L).thenReturn(10L).thenReturn(25L); - ExponentialBackoffRetryLogic retryLogic = newRetryLogic(maxRetryTime, initialDelay, multiplier, 0, clock); + ExponentialBackoffRetryLogic retryLogic = + newRetryLogic(maxRetryTime, initialDelay, multiplier, 0, clock, (ignored) -> {}); Supplier> workMock = newWorkMock(); SessionExpiredException error = sessionExpired(); @@ -731,7 +747,8 @@ void doesNotCollectSuppressedErrorsWhenSameErrorIsThrownRx() { Clock clock = mock(Clock.class); when(clock.millis()).thenReturn(0L).thenReturn(10L).thenReturn(25L); - ExponentialBackoffRetryLogic retryLogic = newRetryLogic(maxRetryTime, initialDelay, multiplier, 0, clock); + ExponentialBackoffRetryLogic retryLogic = + newRetryLogic(maxRetryTime, initialDelay, multiplier, 0, clock, (ignored) -> {}); SessionExpiredException error = sessionExpired(); StepVerifier.create(retryLogic.retryRx(Mono.error(error))) @@ -833,8 +850,8 @@ void eachRetryIsLogged() { Logging logging = mock(Logging.class); Logger logger = mock(Logger.class); when(logging.getLog(any(Class.class))).thenReturn(logger); - ExponentialBackoffRetryLogic logic = - new ExponentialBackoffRetryLogic(RetrySettings.DEFAULT.maxRetryTimeMs(), eventExecutor, clock, logging); + ExponentialBackoffRetryLogic logic = new ExponentialBackoffRetryLogic( + RetrySettings.DEFAULT.maxRetryTimeMs(), eventExecutor, clock, logging, (ignored) -> {}); retry(logic, retries); @@ -1175,8 +1192,8 @@ void shouldRetryWithBackOffRx() { Exception exception = new TransientException("Unknown", "Retry this error."); Clock clock = mock(Clock.class); when(clock.millis()).thenReturn(0L, 100L, 200L, 400L, 800L); - ExponentialBackoffRetryLogic retryLogic = - new ExponentialBackoffRetryLogic(500, 100, 2, 0, eventExecutor, clock, DEV_NULL_LOGGING); + ExponentialBackoffRetryLogic retryLogic = new ExponentialBackoffRetryLogic( + 500, 100, 2, 0, eventExecutor, clock, DEV_NULL_LOGGING, (ignored) -> {}); Flux source = Flux.concat(Flux.range(0, 2), Flux.error(exception)); Flux retriedSource = Flux.from(retryLogic.retryRx(source)); @@ -1195,8 +1212,8 @@ void shouldRetryWithRandomBackOffRx() { Exception exception = new TransientException("Unknown", "Retry this error."); Clock clock = mock(Clock.class); when(clock.millis()).thenReturn(0L, 100L, 200L, 400L, 800L); - ExponentialBackoffRetryLogic retryLogic = - new ExponentialBackoffRetryLogic(500, 100, 2, 0.1, eventExecutor, clock, DEV_NULL_LOGGING); + ExponentialBackoffRetryLogic retryLogic = new ExponentialBackoffRetryLogic( + 500, 100, 2, 0.1, eventExecutor, clock, DEV_NULL_LOGGING, (ignored) -> {}); Flux source = Flux.concat(Flux.range(0, 2), Flux.error(exception)); Flux retriedSource = Flux.from(retryLogic.retryRx(source)); @@ -1229,7 +1246,7 @@ public Void get() { } private CompletionStage retryAsync(ExponentialBackoffRetryLogic retryLogic, int times, Object result) { - return retryLogic.retryAsync(new Supplier>() { + return retryLogic.retryAsync(new Supplier<>() { int invoked; @Override @@ -1265,16 +1282,29 @@ private static List delaysWithoutJitter(long initialDelay, double multipli return values; } - private static List sleepValues(Clock clockMock, int expectedCount) throws InterruptedException { + private static List sleepValues(ExponentialBackoffRetryLogic.SleepTask sleepTask, int expectedCount) + throws InterruptedException { ArgumentCaptor captor = ArgumentCaptor.forClass(long.class); - verify(clockMock, times(expectedCount)).sleep(captor.capture()); + verify(sleepTask, times(expectedCount)).sleep(captor.capture()); return captor.getAllValues(); } private ExponentialBackoffRetryLogic newRetryLogic( - long maxRetryTimeMs, long initialRetryDelayMs, double multiplier, double jitterFactor, Clock clock) { + long maxRetryTimeMs, + long initialRetryDelayMs, + double multiplier, + double jitterFactor, + Clock clock, + ExponentialBackoffRetryLogic.SleepTask sleepTask) { return new ExponentialBackoffRetryLogic( - maxRetryTimeMs, initialRetryDelayMs, multiplier, jitterFactor, eventExecutor, clock, DEV_NULL_LOGGING); + maxRetryTimeMs, + initialRetryDelayMs, + multiplier, + jitterFactor, + eventExecutor, + clock, + DEV_NULL_LOGGING, + sleepTask); } private static ServiceUnavailableException serviceUnavailable() { diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/DriverFactoryWithClock.java b/driver/src/test/java/org/neo4j/driver/internal/util/DriverFactoryWithClock.java index 8a3f07fccc..bef6d39727 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/DriverFactoryWithClock.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/DriverFactoryWithClock.java @@ -18,6 +18,7 @@ */ package org.neo4j.driver.internal.util; +import java.time.Clock; import org.neo4j.driver.internal.DriverFactory; public class DriverFactoryWithClock extends DriverFactory { diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/FakeClock.java b/driver/src/test/java/org/neo4j/driver/internal/util/FakeClock.java index e01a99841b..d6b12f4970 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/FakeClock.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/FakeClock.java @@ -18,49 +18,27 @@ */ package org.neo4j.driver.internal.util; -import java.util.concurrent.PriorityBlockingQueue; -import java.util.concurrent.TimeUnit; +import java.time.Clock; +import java.time.Instant; +import java.time.ZoneId; import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.locks.LockSupport; -public class FakeClock implements Clock { +public class FakeClock extends Clock { private final AtomicLong timestamp = new AtomicLong(); - private final PriorityBlockingQueue threads; - public FakeClock() { - this(false); - } - - private FakeClock(boolean progressOnSleep) { - this.threads = progressOnSleep ? null : new PriorityBlockingQueue(); + @Override + public ZoneId getZone() { + throw new UnsupportedOperationException(); } @Override - public long millis() { - return timestamp.get(); + public Clock withZone(ZoneId zone) { + throw new UnsupportedOperationException(); } @Override - public void sleep(long millis) { - if (millis <= 0) { - return; - } - long target = timestamp.get() + millis; - if (threads == null) { - progress(millis); - } else { - // park until the target time has been reached - WaitingThread token = new WaitingThread(Thread.currentThread(), target); - threads.add(token); - for (; ; ) { - if (timestamp.get() >= target) { - threads.remove(token); - return; - } - // park with a timeout to guarantee that we make progress even if something goes wrong - LockSupport.parkNanos(this, TimeUnit.MILLISECONDS.toNanos(millis)); - } - } + public Instant instant() { + return Instant.ofEpochMilli(timestamp.get()); } public void progress(long millis) { @@ -68,24 +46,5 @@ public void progress(long millis) { throw new IllegalArgumentException("time can only progress forwards"); } timestamp.addAndGet(millis); - if (threads != null) { - // wake up the threads that are sleeping awaiting the current time - for (WaitingThread thread; (thread = threads.peek()) != null; ) { - if (thread.timestamp < timestamp.get()) { - threads.remove(thread); - LockSupport.unpark(thread.thread); - } - } - } - } - - private static class WaitingThread { - final Thread thread; - final long timestamp; - - private WaitingThread(Thread thread, long timestamp) { - this.thread = thread; - this.timestamp = timestamp; - } } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/FixedRetryLogic.java b/driver/src/test/java/org/neo4j/driver/internal/util/FixedRetryLogic.java index f3c6e6707a..38841599f7 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/FixedRetryLogic.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/FixedRetryLogic.java @@ -21,6 +21,7 @@ import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; import io.netty.util.concurrent.EventExecutorGroup; +import java.time.Clock; import org.neo4j.driver.internal.retry.ExponentialBackoffRetryLogic; public class FixedRetryLogic extends ExponentialBackoffRetryLogic { @@ -32,7 +33,7 @@ public FixedRetryLogic(int retryCount) { } public FixedRetryLogic(int retryCount, EventExecutorGroup eventExecutorGroup) { - super(Long.MAX_VALUE, eventExecutorGroup, new SleeplessClock(), DEV_NULL_LOGGING); + super(Long.MAX_VALUE, eventExecutorGroup, Clock.systemUTC(), DEV_NULL_LOGGING, (ignored) -> {}); this.retryCount = retryCount; } diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/MessageRecordingDriverFactory.java b/driver/src/test/java/org/neo4j/driver/internal/util/MessageRecordingDriverFactory.java index f88b6e12f3..12b31319a4 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/MessageRecordingDriverFactory.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/MessageRecordingDriverFactory.java @@ -22,6 +22,7 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelPipeline; import io.netty.handler.codec.MessageToMessageEncoder; +import java.time.Clock; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/SleeplessClock.java b/driver/src/test/java/org/neo4j/driver/internal/util/SleeplessClock.java deleted file mode 100644 index 2998e64959..0000000000 --- a/driver/src/test/java/org/neo4j/driver/internal/util/SleeplessClock.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) "Neo4j" - * Neo4j Sweden AB [http://neo4j.com] - * - * This file is part of Neo4j. - * - * 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 org.neo4j.driver.internal.util; - -public final class SleeplessClock implements Clock { - private final Clock delegate; - - public SleeplessClock() { - this(Clock.SYSTEM); - } - - public SleeplessClock(Clock delegate) { - this.delegate = delegate; - } - - @Override - public long millis() { - return delegate.millis(); - } - - @Override - public void sleep(long millis) throws InterruptedException {} -} diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/io/ChannelTrackingDriverFactory.java b/driver/src/test/java/org/neo4j/driver/internal/util/io/ChannelTrackingDriverFactory.java index 008fe9f94a..c88399142e 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/io/ChannelTrackingDriverFactory.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/io/ChannelTrackingDriverFactory.java @@ -20,6 +20,7 @@ import io.netty.bootstrap.Bootstrap; import io.netty.channel.Channel; +import java.time.Clock; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; @@ -33,7 +34,6 @@ import org.neo4j.driver.internal.metrics.MetricsProvider; import org.neo4j.driver.internal.security.SecurityPlan; import org.neo4j.driver.internal.spi.ConnectionPool; -import org.neo4j.driver.internal.util.Clock; import org.neo4j.driver.internal.util.DriverFactoryWithClock; public class ChannelTrackingDriverFactory extends DriverFactoryWithClock { @@ -42,7 +42,7 @@ public class ChannelTrackingDriverFactory extends DriverFactoryWithClock { private ConnectionPool pool; public ChannelTrackingDriverFactory() { - this(0, Clock.SYSTEM); + this(0, Clock.systemUTC()); } public ChannelTrackingDriverFactory(Clock clock) { diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/io/ChannelTrackingDriverFactoryWithFailingMessageFormat.java b/driver/src/test/java/org/neo4j/driver/internal/util/io/ChannelTrackingDriverFactoryWithFailingMessageFormat.java index 432da52906..72b89d1c1f 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/io/ChannelTrackingDriverFactoryWithFailingMessageFormat.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/io/ChannelTrackingDriverFactoryWithFailingMessageFormat.java @@ -18,6 +18,7 @@ */ package org.neo4j.driver.internal.util.io; +import java.time.Clock; import org.neo4j.driver.Config; import org.neo4j.driver.internal.ConnectionSettings; import org.neo4j.driver.internal.DefaultDomainNameResolver; @@ -25,7 +26,6 @@ import org.neo4j.driver.internal.async.connection.ChannelConnectorImpl; import org.neo4j.driver.internal.cluster.RoutingContext; import org.neo4j.driver.internal.security.SecurityPlan; -import org.neo4j.driver.internal.util.Clock; import org.neo4j.driver.internal.util.FailingMessageFormat; public class ChannelTrackingDriverFactoryWithFailingMessageFormat extends ChannelTrackingDriverFactory {